CF940F Machine Learning

CF940F Machine Learning

题面:Luogu

解析

很简单的一道题。直接套带修改莫队,每次暴力统计答案即可。复杂度有保证吗?当然有,不难发现区间内数字出现次数的mex不会大于\(\sqrt{2*len}\),因为\(\frac{mex(mex-1)}{2} \leq len\)

代码


#include<cstdio>
#include<iostream>
#include<algorithm>
#define N 100005
using namespace std;
inline int In(){
	char c=getchar(); int x=0,ft=1;
	for(;c<'0'||c>'9';c=getchar()) if(c=='-') ft=-1;
	for(;c>='0'&&c<='9';c=getchar()) x=x*10+c-'0';
	return x*ft;
}
const int bc=2154;
int n,m,a[N],p[N],c[N],t[N*2],ans[N],tc=0,qc=0,tim=0;
struct Q{
	int l,r,t,id;
	bool operator < (const Q& f) const {
		return l/bc==f.l/bc?(r/bc==f.r/bc?t<f.t:r<f.r):l<f.l;
	}
}q[N];
int nl,nr,nt,cnt[N*2],cap[N];
inline void add(int x){ if(cnt[a[x]]>=0) --cap[cnt[a[x]]]; ++cnt[a[x]]; if(cnt[a[x]]>=0) ++cap[cnt[a[x]]]; }
inline void del(int x){ if(cnt[a[x]]>=0) --cap[cnt[a[x]]]; --cnt[a[x]]; if(cnt[a[x]]>=0) ++cap[cnt[a[x]]]; }
inline void upd(int t){
	if(nl<=p[t]&&p[t]<=nr) del(p[t]);
	swap(a[p[t]],c[t]);
	if(nl<=p[t]&&p[t]<=nr) add(p[t]);
}
inline int Calc(){ for(int i=1;;++i) if(!cap[i]) return i; }
int main(){
	n=In(); m=In();
	for(int i=1;i<=n;++i) a[i]=t[++tc]=In();
	for(int i=1,op,x,y;i<=m;++i){
		op=In(); x=In(); y=In();
		if(op==1) q[++qc]=(Q){x,y,tim,qc};
		else p[++tim]=x,c[tim]=t[++tc]=y;
	}
	sort(t+1,t+1+tc); tc=unique(t+1,t+1+tc)-t-1;
	for(int i=1;i<=n;++i) a[i]=lower_bound(t+1,t+1+tc,a[i])-t;
	for(int i=1;i<=tim;++i) c[i]=lower_bound(t+1,t+1+tc,c[i])-t;
	sort(q+1,q+1+qc); nl=1,nr=0,nt=0;
	for(int i=1,ql,qr,qt;i<=qc;++i){
		ql=q[i].l; qr=q[i].r; qt=q[i].t;
		while(ql<nl) add(--nl); while(ql>nl) del(nl++);
		while(qr<nr) del(nr--); while(qr>nr) add(++nr);
		while(qt<nt) upd(nt--); while(qt>nt) upd(++nt);
		ans[q[i].id]=Calc();
	}
	for(int i=1;i<=qc;++i) printf("%d\n",ans[i]);
	return 0;
}

posted @ 2019-03-26 22:03  pkh68  阅读(137)  评论(0编辑  收藏  举报