CF940F Machine Learning
思路
带修莫队的题目
找答案可以直接暴力
因为答案是\(O(\sqrt{n})\)级别的
懒得证明了
代码
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <map>
#include <cmath>
using namespace std;
int L,R,T,a[200100],b[200100],ans[200100],num_cnt,color[200100],times[200100],sz,belong[200100],n,m,Acnt,Qcnt;
map<int,int> M;
struct Query{
int l,r,t,id;
bool operator < (const Query & b) const {
return (belong[l]==belong[b.l])?(belong[r]==belong[b.r]?t<b.t:belong[r]<belong[b.r]):belong[l]<belong[b.l];
}
}Q[200100];
struct Modi{
int pos,before,after;
}A[200100];
void init(void){
sz=pow(n,0.666666);
for(int i=1;i<=n;i++)
belong[i]=(i-1)/sz+1;
}
int getans(void){
for(int i=1;1;i++)
if(times[i]<=0)
return i;
}
void moveT(int t,int opt){
if(opt==1){
if(A[t].pos>=L&&A[t].pos<=R){
times[color[A[t].before]]--;
color[A[t].before]--;
times[color[A[t].before]]++;
times[color[A[t].after]]--;
color[A[t].after]++;
times[color[A[t].after]]++;
}
a[A[t].pos]=A[t].after;
}
else{
if(A[t].pos>=L&&A[t].pos<=R){
times[color[A[t].after]]--;
color[A[t].after]--;
times[color[A[t].after]]++;
times[color[A[t].before]]--;
color[A[t].before]++;
times[color[A[t].before]]++;
}
a[A[t].pos]=A[t].before;
}
T+=opt;
}
void moveL(int opt){
if(opt==1){
times[color[a[L]]]--;
color[a[L]]--;
times[color[a[L]]]++;
L++;
}
else{
L--;
times[color[a[L]]]--;
color[a[L]]++;
times[color[a[L]]]++;
}
}
void moveR(int opt){
if(opt==1){
R++;
times[color[a[R]]]--;
color[a[R]]++;
times[color[a[R]]]++;
}
else{
times[color[a[R]]]--;
color[a[R]]--;
times[color[a[R]]]++;
R--;
}
}
int main(){
scanf("%d %d",&n,&m);
init();
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
if(!M[a[i]])
M[a[i]]=++num_cnt;
a[i]=b[i]=M[a[i]];
}
for(int i=1;i<=m;i++){
int opt,x,y;
scanf("%d %d %d",&opt,&x,&y);
if(opt==1){
++Qcnt;
Q[Qcnt].id=Qcnt;
Q[Qcnt].l=x;
Q[Qcnt].r=y;
Q[Qcnt].t=Acnt;
}
else{
++Acnt;
A[Acnt].pos=x;
if(!M[y])
M[y]=++num_cnt;
y=M[y];
A[Acnt].before=b[x];
A[Acnt].after=y;
b[x]=y;
}
}
sort(Q+1,Q+Qcnt+1);
L=1;
R=0;
T=0;
times[0]=num_cnt;
for(int i=1;i<=Qcnt;i++){
while(L>Q[i].l)
moveL(-1);
while(R<Q[i].r)
moveR(1);
while(L<Q[i].l)
moveL(1);
while(R>Q[i].r)
moveR(-1);
while(T<Q[i].t)
moveT(T+1,1);
while(T>Q[i].t)
moveT(T,-1);
ans[Q[i].id]=getans();
}
for(int i=1;i<=Qcnt;i++)
printf("%d\n",ans[i]);
return 0;
}