列表

详情


NC213219. 最优的连续子段

描述

给定一个长度为n的序列,需要找出一段最优的连续子段,使得出现在子段中出现次数为1次的数字最多(多一次少一次都不行,只要一次)。
求最优连续子段中出现次数为1次的数字个数。

输入描述


输出描述

共一行,输出最多的个数。

示例1

输入:

4
1 2 1 2

输出:

2

说明:

最优子段可以是区间[1,2],[2,3],[3,4],出现一次的数字都是2个

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(clang++11) 解法, 执行用时: 49ms, 内存消耗: 3192K, 提交时间: 2020-11-13 17:18:04

#include<bits/stdc++.h>
#define lson k<<1
#define rson k<<1|1
using namespace std;
const int N=300010;
int n;
int res;
int R[N],H[N],tr[N*4],lz[N*4];
void update(int l,int r,int L,int R,int f,int k) {
	if(L<=l&&r<=R) {
		tr[k]+=f,lz[k]+=f;
		return;
	}
	int mid=(l+r)>>1;
	if(L<=mid) update(l,mid,L,R,f,lson);
	if(R>mid) update(mid+1,r,L,R,f,rson);
	tr[k]=max(tr[lson],tr[rson])+lz[k];
}
int main() {
	scanf("%d",&n);
	for(int i=1; i<=n; i++) {
		int x;
		scanf("%d",&x);
		R[H[x]]=i,H[x]=i;
	}
	for(int i=1; i<=n; i++)
		if(!R[i]) R[i]=n+1;
	for(int i=n; i; i--) {
		int x=R[i],y=R[x];
		if(x) {
			if(y) update(1,n,x,y-1,-1,1);
			update(1,n,i,x-1,1,1);
		}
		res=max(res,tr[1]);
	}
	printf("%d\n",res);
	return 0;
}

上一题