记录编号 477437 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [国家集训队2011]数颜色 最终得分 100
用户昵称 GravatarHallmeow 是否通过 通过
代码语言 C++ 运行时间 1.652 s
提交时间 2017-12-03 14:04:20 内存使用 50.21 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<cstring>
#include<set>
#include<vector>
using namespace std;
#define pos(i,a,b) for(int i=(a);i<=(b);i++)
#define N 10100
#define lc(x) (tree[x].lc)
#define rc(x) (tree[x].rc)
#include<algorithm>
int lowbit(int x){
	return x&(-x);
}
int n,m;
int a[N];
int pre[N],hou[N];
set<int> s[1001000];
vector<int> v[1001000];
int cnt[1001000],size;
struct haha{
	int lc,rc,sum;
}tree[N*100];
int root[N];
void update(int &rt,int pos,int num,int l,int r){
	if(!rt) rt=++size;
	if(l==r){
		tree[rt].sum+=num;return;
	}
	int mid=(l+r)>>1;
	if(pos<=mid) update(lc(rt),pos,num,l,mid);
	else update(rc(rt),pos,num,mid+1,r);
	tree[rt].sum=tree[lc(rt)].sum+tree[rc(rt)].sum;
}
void add(int x,int pos,int num){
	while(x<=n){
		update(root[x],pos,num,0,n);
		x+=lowbit(x);
	}
}
int cunx[100],cuny[100];
int query(int l,int r,int xl,int xr){
	int sumx(0),sumy(0);
	pos(i,1,cunx[0]) sumx+=tree[cunx[i]].sum;
	pos(i,1,cuny[0]) sumy+=tree[cuny[i]].sum;
	if(l>=xl&&r<=xr) return sumy-sumx;
	int ans(0);
	int mid=(l+r)>>1;
	int tempx[52],tempy[52];
	pos(i,0,cunx[0]) tempx[i]=cunx[i];
	pos(i,0,cuny[0]) tempy[i]=cuny[i];
	if(xl<=mid){
		pos(i,1,cunx[0]) cunx[i]=lc(cunx[i]);
		pos(i,1,cuny[0]) cuny[i]=lc(cuny[i]);
		ans+=query(l,mid,xl,xr);
		pos(i,0,tempx[0]) cunx[i]=tempx[i];
		pos(i,0,tempy[0]) cuny[i]=tempy[i];
	} 
	if(xr>mid){
		pos(i,1,cunx[0]) cunx[i]=rc(cunx[i]);
		pos(i,1,cuny[0]) cuny[i]=rc(cuny[i]);
		ans+=query(mid+1,r,xl,xr);
		pos(i,0,tempx[0]) cunx[i]=tempx[i];
		pos(i,0,tempy[0]) cuny[i]=tempy[i];
	} 
	return ans;
}
int Query(int x,int y){
	x--;
	cunx[0]=cuny[0]=0;
	int tx=x,ty=y;
	while(tx>0){
		cunx[++cunx[0]]=root[tx];tx-=lowbit(tx);
	}
	while(ty>0){
		cuny[++cuny[0]]=root[ty];ty-=lowbit(ty);
	}
	return query(0,n,0,x);
}
int main(){
	freopen("nt2011_color.in","r",stdin);
	freopen("nt2011_color.out","w",stdout);
	scanf("%d%d",&n,&m);
	pos(i,1,n){
		scanf("%d",&a[i]);
		pre[i]=0;hou[i]=n+1;
		if(!v[a[i]].empty()){
			pre[i]=v[a[i]][cnt[a[i]]-1];
			hou[v[a[i]][cnt[a[i]]-1]]=i;
		}
		v[a[i]].push_back(i);cnt[a[i]]++;
		s[a[i]].insert(i);
		add(i,pre[i],1);
	}
	pos(i,1,m){
		char c;cin>>c;
		int x,y;scanf("%d%d",&x,&y);
		if(c=='Q'){
			printf("%d\n",Query(x,y));
		}
		else{
			set<int>::iterator it1,it2,it3;
			it1=lower_bound(s[a[x]].begin(),s[a[x]].end(),x);
			if(s[a[x]].size()>1){
				if(it1==s[a[x]].begin()){
					add(x,0,-1);
					it2=++it1;it1--;
					add(*it2,x,-1);
					add(*it2,0,1);
				}
				else{
					if(it1==s[a[x]].end()){
						it2=--it1;it1++;
						add(x,*it2,-1);
					}
					else{
						it2=--it1;it1++;it3=++it1;it1--;
						add(*it3,x,-1);add(*it3,*it2,1);
						add(x,*it2,-1);
					}
				}
			}
			else{
				add(x,0,-1);
			}
			s[a[x]].erase(x);
			a[x]=y;
			s[y].insert(x);
			it1=lower_bound(s[y].begin(),s[y].end(),x);
			if(s[y].size()>1){
				if(it1==s[y].begin()){
					it2=++it1;it1--;
					add(*it2,0,-1);add(*it2,x,1);add(x,0,1);
				}
				else{
					if(it1==s[y].end()){
						it2=--it1;it1++;add(x,*it2,1);
					}
					else{
						it2=--it1;it1++;it3=++it1;it1--;
						add(*it3,*it2,-1);add(*it3,x,1);add(x,*it2,1);
					}
				}
			}
			else{
				add(x,0,1);
			}
		}
	}
	return 0;
}