带修莫队,自闭,人傻常数大
查看原帖
带修莫队,自闭,人傻常数大
175829
cnyzz楼主2020/5/16 16:47
#include <bits/stdc++.h>
using namespace std;
const int N=133333+10;
int n,m;
int pos[N],co[N],len;
struct query {
	int l,r,pre,id;
} q[N];
struct change {
	int x,y;
} c[N];
int qn,cn;
char opt;
void build() {
	for(int i=1;i<=n;i++)
		pos[i]=(i-1)/len+1;
}
bool cmp(query _,query __) {
	return (_.l/len)==(__.l/len)?_.r<__.r:(_.l/len)<(__.l/len);
}
int ans,L=1,R,now,cnt[1000010],tans[N];
void add(int x) {
	if(++cnt[x]==1)
		ans++;
	//printf("use add %d\n",ans);
}
void del(int x) {
	if(--cnt[x]==0)
		ans--;
	//printf("use del %d\n",ans);
}
void work(int t,int i) {
	if(c[t].x<=q[i].r&&c[t].x>=q[i].l) {
		if(--cnt[co[c[t].x]]==0)
			ans--;
		if(++cnt[c[t].y]==1)
			ans++;
	}
	swap(co[c[t].x],c[t].y);
	//printf("%d use change %d: %d to %d,ans change to %d\n",i,t,c[t].x,c[t].y,ans);
}
int main() {
	scanf("%d %d",&n,&m);
	len=sqrt(n);
	build();
	for(int i=1;i<=n;i++)
		scanf("%d",&co[i]);
	for(int i=1;i<=m;i++) {
		cin>>opt;
		if(opt=='Q') {
			++qn;
			scanf("%d %d",&q[qn].l,&q[qn].r);
			q[qn].pre=cn,q[qn].id=qn;
			//printf("%d %d\n",q[qn].l,q[qn].r);
		}
		else if(opt=='R') {
			++cn;
			scanf("%d %d",&c[cn].x,&c[cn].y);
		}
	}
	//printf("%d\n",q[1].id);
	sort(q+1,q+qn+1,cmp);
	//printf("%d\n",q[1].id);
	for(int i=1;i<=qn;i++) {
		//printf("%d\n",q[i].id);
		while(R<q[i].r) add(co[++R]);
		while(R>q[i].r) del(co[R--]);
		while(L<q[i].l) del(co[L++]);
		while(L>q[i].l) add(co[--L]);
		while(now<q[i].pre) work(++now,i);
		while(now>q[i].pre) work(now--,i);
		tans[q[i].id]=ans;
		//puts("");
	}
	for(int i=1;i<=qn;i++)
		printf("%d\n",tans[i]);
	return 0;
}
2020/5/16 16:47
加载中...