bzoj 2120 数颜色

Description

墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问。墨墨会像你发布如下指令: 1、 Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔。 2、 R P Col 把第P支画笔替换为颜色Col。为了满足墨墨的要求,你知道你需要干什么了吗?

Input

第1行两个整数N,M,分别代表初始画笔的数量以及墨墨会做的事情的个数。第2行N个整数,分别代表初始画笔排中第i支画笔的颜色。第3行到第2+M行,每行分别代表墨墨会做的一件事情,格式见题干部分。

Output

对于每一个Query的询问,你需要在对应的行中给出一个数字,代表第L支画笔到第R支画笔中共有几种不同颜色的画笔。

Sample Input

6 5
1 2 3 4 5 5
Q 1 4
Q 2 6
R 1 2
Q 1 4
Q 2 6

Sample Output

4
4
3
4
带修改的莫队
因为修改次数不多,所以在移动左右指针时还要移动一个修改操作指针
确保查询时正好在某次修改的状态
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 struct Node
 8 {
 9   int x,y,pre,id,ans;
10 }q[10005],p[10005];
11 int n,m,lim,cntq,cntp,curl,curr,ans,cnt[1000005],a[10005],path[10005],curp,kp[10005];
12 char opt;
13 bool cmp(Node a,Node b)
14 {
15   if (a.x/lim==b.x/lim) return a.y<b.y;
16   return a.x<b.x;
17 }
18 void update(int x,int y,int l,int r)
19 {
20   if (l<=x&&x<=r)
21     {
22       ans-=(--cnt[a[x]]==0);
23       ans+=(++cnt[y]==1);
24       a[x]=y;
25     }
26   else a[x]=y;
27 }
28 char get()
29 {
30   char c=getchar();
31   while (c!='Q'&&c!='R') c=getchar();
32   return c;
33 }
34 int main()
35 {int i,j,x,y;
36   cin>>n>>m;
37   lim=sqrt(n);
38   for (i=1;i<=n;i++)
39     scanf("%d",&a[i]),path[i]=a[i];
40   for (i=1;i<=m;i++)
41     {
42       opt=get();
43       scanf("%d%d",&x,&y);
44       if (opt=='Q')
45     {
46       q[++cntq].x=x;q[cntq].y=y;
47       q[cntq].pre=cntp;q[cntq].id=cntq;
48     }
49       else if (opt=='R')
50     {
51       p[++cntp].x=x;p[cntp].y=y;p[cntp].pre=path[x];
52       path[x]=y;
53     }
54     }
55   sort(q+1,q+cntq+1,cmp);
56   curl=1;curr=0;curp=0;
57   for (i=1;i<=cntq;i++)
58     {
59       int P=q[i].pre,L=q[i].x,R=q[i].y;
60       while (curp>P) update(p[curp].x,p[curp].pre,curl,curr),curp--;
61       while (curp<P) curp++,update(p[curp].x,p[curp].y,curl,curr);
62       while (curl<L) ans-=(--cnt[a[curl++]] ==0);
63       while (curl>L) ans+=(++cnt[a[--curl]] ==1);
64       while (curr<R) ans+=(++cnt[a[++curr]] ==1);
65       while (curr>R) ans-=(--cnt[a[curr--]] ==0);
66       kp[q[i].id]=ans;
67     }
68   for (i=1;i<=cntq;i++)
69     printf("%d\n",kp[i]);
70 }

 

posted @ 2017-12-27 14:01  Z-Y-Y-S  阅读(163)  评论(0编辑  收藏  举报