题目描述
墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问。墨墨会向你发布如下指令:
1、 Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔。
2、 R P Col 把第P支画笔替换为颜色Col。
为了满足墨墨的要求,你知道你需要干什么了吗?
输入输出格式
输入格式:
第1行两个整数N,M,分别代表初始画笔的数量以及墨墨会做的事情的个数。
第2行N个整数,分别代表初始画笔排中第i支画笔的颜色。
第3行到第2+M行,每行分别代表墨墨会做的一件事情,格式见题干部分。
输出格式:
对于每一个Query的询问,你需要在对应的行中给出一个数字,代表第L支画笔到第R支画笔中共有几种不同颜色的画笔。
输入输出样例
输入样例#1: 复制
6 5 1 2 3 4 5 5 Q 1 4 Q 2 6 R 1 2 Q 1 4 Q 2 6
输出样例#1: 复制
View Code
4 4 3 4
为带修莫队 增加一维即可解决
如果还按照原来的方式cmp的话T到飞起 增加的那一维也要排序!!!
因为要来回的修改 与退回
所以swap非常的巧妙
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; //input by bxd #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define repp(i,a,b) for(int i=(a);i>=(b);--i) #define RI(n) scanf("%d",&(n)) #define RII(n,m) scanf("%d%d",&n,&m) #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k) #define RS(s) scanf("%s",s); #define ll long long #define pb push_back #define CLR(A,v) memset(A,v,sizeof A) #define inf 0x3f3f3f3f #define lson l,m,pos<<1 #define rson m+1,r,pos<<1|1 ////////////////////////////////////// const int N=1e6+4; struct node { int l,r,pre,id; }s[N]; struct query { int val,pos; }s2[N]; int n,m,a[N],L,R,now,ans,anss[N],cnt[N],cntq,cntr,x,y,block; char ss[2]; bool cmp(node a,node b) { return a.l/block==b.l/block? a.r/block==b.r/block? a.pre<b.pre: a.r<b.r: a.l<b.l;//三个元素玄学排序 } void add(int x) { if(++cnt[a[x]]==1)ans++; } void del(int x) { if(--cnt[a[x]]==0)ans--; } void work(int now,int i) { if(s2[now].pos>=s[i].l&&s2[now].pos<=s[i].r) { if(--cnt[ a[s2[now].pos] ]==0)ans--; if(++cnt[ s2[now].val ]==1)ans++; } swap(s2[now].val,a[s2[now].pos]); } int main() { RII(n,m);rep(i,1,n)RI(a[i]); rep(i,1,m) { RS(ss);RII(x,y); if(ss[0]=='Q') { s[++cntq].l=x;s[cntq].r=y;s[cntq].pre=cntr;s[cntq].id=cntq; } else { s2[++cntr].pos=x;s2[cntr].val=y; } } block=sqrt(n)*15; sort(s+1,s+1+cntq,cmp); int L=1,R=0,now=0; rep(i,1,cntq) { int l=s[i].l,r=s[i].r; while(L<l)del(L++); while(L>l)add(--L); while(R<r)add(++R); while(R>r)del(R--); while(now<s[i].pre)work(++now,i); while(now>s[i].pre)work(now--,i); anss[s[i].id]=ans; } rep(i,1,cntq)cout<<anss[i]<<endl; return 0; }