2019 Multi-University Training Contest 2: Longest Subarray

Keywords: PHP

Topic link: http://acm.hdu.edu.cn/showproblem.php?pid=6602

Solution: If the right endpoint is fixed, the feasible left endpoint of each element is two consecutive intervals (number & gt; = K & gt; = k > = K and = 0 = 0 = 0), scan the right endpoint, and maintain the feasible interval of each element's left endpoint with the maximum value of the line segment tree, and do the interval + 1 in the feasible interval of each element's left endpoint. When updating the answer, the search value is the lowest subscript value of C (the value of C means that C elements are feasible in this location). Searching and pruning on the online segment tree, because the interval of each search is [1,i], the complexity of each query after pruning is still nlognnlogn. When moving the right endpoint, only the feasible interval of the newly included element will be changed. The maintenance complexity of each moving right endpoint is nlognnlogn. Note that each element does not maintain the interval that has been maintained repeatedly.

#include<bits/stdc++.h>
using namespace std;
#define lson rt << 1,l,mid
#define rson rt << 1 | 1,mid + 1,r
const int maxn = 1e5 + 10;
int val[maxn << 2],laz[maxn << 2],p[maxn << 2];
int n,c,k;
vector<int> g[maxn];
void up(int rt) {
	val[rt] = max(val[rt << 1],val[rt << 1 | 1]);
}
void down(int rt) {
	if(!laz[rt]) return;
	val[rt << 1] += laz[rt];
	laz[rt << 1] += laz[rt];
	val[rt << 1 | 1] += laz[rt];
	laz[rt << 1 | 1] += laz[rt];
	laz[rt] = 0; 
}
void build(int rt,int l,int r) {
	val[rt] = laz[rt] = 0;
	if(l == r) {
		p[l] = rt;
		return ;
	}
	int mid = l + r >> 1;
	build(lson);build(rson);
}
void upd(int L,int R,int v,int rt,int l,int r) {
	if(L > R) return ;
	if(L <= l && r <= R) {
		laz[rt] += v;
		val[rt] += v;
		return ;
	}
	down(rt);
	int mid = l + r >> 1;
	if(L <= mid) upd(L,R,v,lson);
	if(mid + 1 <= R) upd(L,R,v,rson);
	up(rt);
}
int qry(int L,int R,int v,int rt,int l,int r) {
	if(L > R) return 0;
	if(val[rt] != c || (l < l && r > R)) return 0;
	if(l == r) return l;
	int mid = l + r >> 1;
	down(rt);
	if(L <= mid) {
		int t = qry(L,R,v,lson);
		if(t) return t;
	}
	if(mid + 1 <= R) return qry(L,R,v,rson);
}
int main() {
	//freopen("in.txt","r",stdin);
	while(~scanf("%d%d%d",&n,&c,&k)) {
		int x;
		build(1,1,n);
		for(int i = 1; i <= c; i++) {
			g[i].clear();
			g[i].push_back(0);
		}
		int ans = 0;
		for(int i = 1; i <= n; i++) {
			scanf("%d",&x);
			upd(i,i,c - 1,1,1,n);
			upd(g[x].back() + 1,i - 1,-1,1,1,n);
			g[x].push_back(i);
			int p = (int)g[x].size() - k - 1;
			if(p >= 0) 			
				upd(g[x][p] + 1,g[x][p + 1],1,1,1,n);
			int t = qry(1,i,c,1,1,n);
			if(t)
				ans = max(ans,i - t + 1);
		}
		printf("%d\n",ans);
	}
	return 0;
}

Posted by Acs on Thu, 10 Oct 2019 11:57:32 -0700