2120: 数颜色(待修改的莫队)

2120: 数颜色

Time Limit: 6 Sec  Memory Limit: 259 MB
Submit: 11475  Solved: 4766
[Submit][Status][Discuss]

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

HINT

 

对于100%的数据,N≤10000,M≤10000,修改操作不多于1000次,所有的输入数据中出现的所有整数均大于等于1且不超过10^6。


2016.3.2新加数据两组by Nano_Ape

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int N=1e4+4,M=1e6+5;
 5 int arr[N],save[N],cnt[M],xuhao[N];
 6 int n,m,L,R,res;
 7 
 8 struct Node{
 9     int l,r,id,tim,ans;
10     bool operator<(const Node&X)const{
11         if(ans!=X.ans) return ans<X.ans;
12         if(r!=X.r) return r<X.r;
13         return tim<X.tim;  //修改的时间
14     }
15 }A[N];
16 
17 struct Point{
18     int x,ya,yb;
19 }B[N];
20 
21 void del(int ee){   //传的是值
22     cnt[ee]--;
23     if(cnt[ee]==0) res--;
24 }
25 
26 void add(int ee){
27     if(cnt[ee]==0) res++;
28     cnt[ee]++;
29 }
30 
31 int main(){
32     scanf("%d%d",&n,&m);
33     for(int i=1;i<=n;i++) scanf("%d",&arr[i]),save[i]=arr[i];
34     int big=sqrt(n);
35     char s[10];
36     int cnt1=0,cnt2=0;
37     for(int i=1,d1,d2;i<=m;i++){
38         scanf("%s",s);
39         scanf("%d%d",&d1,&d2);
40         if(s[0]=='Q'){
41             A[++cnt1]={d1,d2,cnt1,cnt2,(d1-1)/big+1};
42         }
43         else{
44             B[++cnt2]={d1,save[d1],d2},save[d1]=d2;   //把d1位置的数改成d2,有可能重读修改一个位置的值所以save保存修改后的值
45         }
46     }
47     sort(A+1,A+1+cnt1);
48     L=1,R=0;
49     int tim=0;   //时间戳
50     for(int i=1;i<=cnt1;i++){
51         while(tim<A[i].tim){   //没有修改过就修改
52             int x=B[++tim].x;
53             if(x>=L&&x<=R){
54                 del(B[tim].ya);
55                 add(B[tim].yb);
56             }
57             arr[x]=B[tim].yb;
58         }
59         while(tim>A[i].tim){ //修改过头了返回回来
60             int x=B[tim].x;
61             if(x>=L&&x<=R){
62                 del(B[tim].yb);
63                 add(B[tim].ya);
64             }
65             arr[x]=B[tim].ya;
66             tim--;   //先修改
67         }
68         while(L<A[i].l) del(arr[L++]);
69         while(L>A[i].l) add(arr[--L]);
70         while(R>A[i].r) del(arr[R--]);
71         while(R<A[i].r) add(arr[++R]);
72         xuhao[A[i].id]=res;
73     }
74     for(int i=1;i<=cnt1;i++) printf("%d\n",xuhao[i]);
75     return 0;
76 }
View Code

 

posted @ 2019-08-17 22:38  厂长在线养猪  Views(154)  Comments(0Edit  收藏  举报