CF1129D Isolation 题解

挨个加入每一个点,维护每一个点之前第一个和他相同的数,每加入一个新点最多影响两个区间的数出现恰好一次的个数,使用分块,二分查找,暴力\(O(n \log2 n)\)的复杂度即可。

代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e5+10;
const int gen=500;
int len,zg,n,m,dp[maxn],t[maxn],lst[maxn],shu[maxn],now,a[maxn];
struct node{
	int x;
	int y;
};
bool cmp(node q,node w){
	return q.x<w.x;
}
struct edge{
	int L,R,mid,sz,qi,tag,zh[gen],he;
	node val[gen];
	void build(){
		for(int i=1;i<=sz;i++){
			val[i].x+=tag;
		}
		sort(val+1,val+1+sz,cmp);
		tag=0;
		for(int i=1;i<=sz;i++){
			zh[i]=zh[i-1]+dp[val[i].y];
		}
		return;
	}
	void init(int q,int w){
		sz=w-q+1;
		qi=q-1;
		for(int i=1;i<=sz;i++){
			val[i].y=q+i-1;
		}
		build();
		return;
	}
	void add(int l,int r,int q){
		if(l==1&&r==sz){
			tag+=q;
		}
		else{
			for(int i=1;i<=sz;i++){
				if(l+qi<=val[i].y&&val[i].y<=r+qi){
					val[i].x+=q;
				}
			}
			build();
		}
		return;
	}
	int query(){
		he=0;
		L=1,R=sz;
		while(L<=R){
			mid=(L+R)/2;
			if(val[mid].x+tag<=m){
				L=mid+1;
				he=zh[mid];
			}
			else{
				R=mid-1;
			}
		}
		return he;
	}
}kuai[gen];
void adds(int l,int r,int q){
//	cout<<"C"<<l<<' '<<r<<' '<<q<<'\n';
	if(shu[l]==shu[r]){
//		cout<<l-kuai[shu[l]].qi<<' '<<r-kuai[shu[l]].qi<<' '<<kuai[shu[l]].sz<<'\n';
		kuai[shu[l]].add(l-kuai[shu[l]].qi,r-kuai[shu[l]].qi,q);
	}
	else{
		kuai[shu[l]].add(l-kuai[shu[l]].qi,kuai[shu[l]].sz,q);
		kuai[shu[r]].add(1,r-kuai[shu[r]].qi,q);
		for(int i=shu[l]+1;i<shu[r];i++){
			kuai[i].add(1,kuai[i].sz,q);
		}
	}
//	if(kuai[1].val[1].y==1){
//		cout<<kuai[1].val[1].x<<' '<<kuai[1].tag<<"YYYYYYYYYYYYYYY"<<'\n';
//	}
//	else{
//		cout<<kuai[1].val[2].x<<' '<<kuai[1].tag<<"YYYYYYYYYYYYYYY"<<'\n';
//	}
	return;
}
signed main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		lst[i]=t[a[i]];
		t[a[i]]=i;
	}
	len=2;
	dp[1]=1;
	for(int i=1,j;i<=n;i=j+1){
		j=min(n,i+len-1);
		zg++;
		kuai[zg].init(i,j);
		for(int k=i;k<=j;k++){
			shu[k]=zg;
		}
	}
	for(int i=1;i<=n;i++){
		adds(lst[i]+1,i,1);
		if(lst[i]){
			adds(lst[lst[i]]+1,lst[i],-1);
		}
		now=0;
		for(int j=1;j<=zg;j++){
			now+=kuai[j].query();
//			cout<<i<<' '<<j<<' '<<kuai[j].query()<<"Yes"<<'\n';
		}
//		cout<<now<<'\n';
		if(i+1<=n){
			dp[i+1]=now;
			kuai[shu[i+1]].build();
		}
	}
	cout<<now;
	return 0;
}
posted @ 2025-04-29 09:54  特别之处  阅读(18)  评论(0)    收藏  举报