BZOJ2120/洛谷P1903 [国家集训队] 数颜色 [带修改莫队]

  BZOJ传送门洛谷传送门

数颜色

题目描述

墨墨购买了一套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: 复制
4
4
3
4

  分析:

  一开始不会打带修改莫队,就直接打了个不带分块的普通莫队,然后在洛谷水了40分,然后看了某位大佬的博客以后,会了带修改莫队,结果被洛谷数据卡常卡了一个小时,这数据也太可怕了吧。。。给出数据的人跪了Orz。。。(BZOJ上的数据一遍就过了。。。)把能用的优化都丢进去了,然后8000+ms过的。。。如果不会带修改莫队,请参考这位大佬的博客。这里蒟蒻就只放代码了。

  Code:

 1 //It is made by HolseLee on 31st May 2018
 2 //Luogu.org P1903
 3 #include<bits/stdc++.h>
 4 #define swap(x,y) x^=y,y^=x,x^=y
 5 using namespace std;
 6 const int N=5e4+7;
 7 const int M=1e6+7;
 8 int n,m,s,L,R,tot,ans[N];
 9 int a[N],c[M],rn,qn;
10 struct Node{
11     int x,y,id,pos;
12     friend bool operator < (const Node a,const Node b){
13         if((a.x-1)/s!=(b.x-1)/s)return ((a.x-1)/s)<((b.x-1)/s);
14         if((a.y-1)/s!=(b.y-1)/s)return ((a.y-1)/s)<((b.y-1)/s);
15         return a.id<b.id;
16     }
17 }Q[N];
18 struct Num{
19 int x,y;}C[N];
20 char obuf[1<<24], *O=obuf;
21 inline int read()
22 {
23     char ch=getchar();int num=0;
24     while(ch<'0'||ch>'9')ch=getchar();
25     while(ch>='0'&&ch<='9'){
26     num=num*10+ch-'0';ch=getchar();}
27     return num;
28 }
29 inline void print(int x)
30 {
31     if(x>9)print(x/10);
32     *O++ = x%10+'0'; 
33 }
34 inline void change(int x,int i)
35 {
36     if(Q[i].x<=C[x].x&&C[x].x<=Q[i].y){
37         if(--c[a[C[x].x]]==0)tot--;
38         if(++c[C[x].y]==1)tot++; }
39     swap(a[C[x].x],C[x].y);
40 }
41 inline void add(int x)
42 {if(++c[a[x]]==1)tot++;}
43 inline void del(int x)
44 {if(--c[a[x]]==0)tot--;}
45 inline void work()
46 {
47     sort(Q+1,Q+qn+1);int now=0;
48     for(int i=1;i<=qn;i++){
49         while(L<Q[i].x)del(L++);
50         while(L>Q[i].x)add(--L);
51         while(R<Q[i].y)add(++R);
52         while(R>Q[i].y)del(R--);
53         while(now<Q[i].id){change(++now,i);}
54         while(now>Q[i].id){change(now--,i);}
55         ans[Q[i].pos]=tot;}
56     for(int i=1;i<=qn;i++)
57     {print(ans[i]);*O++ = '\n';}
58 }
59 int main()
60 {
61     n=read();m=read();
62     for(int i=1;i<=n;i++)a[i]=read();
63     for(int i=1;i<=m;i++){
64     char ch[5];scanf("%s",ch);
65     int x=read();int y=read();
66     if(ch[0]=='R'){C[++rn].x=x;C[rn].y=y;}
67     else {Q[++qn].x=x;Q[qn].y=y;
68     Q[qn].id=rn;Q[qn].pos=qn;}}
69     s=ceil(exp((log(n)+log(qn))/3));L=1;R=0;
70     work();fwrite(obuf, O-obuf, 1, stdout);
71     return 0;
72 }

猜你喜欢

转载自www.cnblogs.com/cytus/p/9118974.html
今日推荐