bzoj2120: 数颜色 [莫队][分块]

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。



带修改莫队膜版

没写过莫队就写带修改心中慌张

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7
 8 struct ask{
 9     int L,R,id,tm;
10 };
11
12 struct req{
13     int ps,cl,pre;
14 };
15
16 const int maxn=10005,maxnum=1000005,maxm=200005,maxr=1005;
17
18 int CL=1,CR=0,ans=0,tim,n,m,k,cnt=0,sz=0;
19 int color[maxn],num[maxnum];
20 int las[maxn],answer[maxm];
21 bool vis[maxn];
22 ask e[maxm];
23 req w[maxr];
24
25 inline bool cmp(const ask &n1,const ask &n2){
26     return (n1.L/tim)==(n2.L/tim)?n1.R<n2.R:n1.L<n2.L;
27 }
28
29 void cala(int x){
30     if(vis[x]){
31         if((--num[color[x]])==0)  --ans;
32     }
33     else{
34         if((++num[color[x]])==1)  ++ans;
35     }
36     vis[x]=!vis[x];
37 }
38
39 void change(int x,int c){
40     if(vis[x]){  cala(x);  color[x]=c;  cala(x);  }
41     else  color[x]=c;
42 }
43
44 int main(){
45     //freopen("temp.in","r",stdin);
46     char opt[2];
47     int x,y;
48     scanf("%d%d",&n,&m);
49     tim=sqrt(n);
50
51     for(int i=1;i<=n;i++){
52         scanf("%d",&color[i]);
53         las[i]=color[i];
54     }
55
56     for(int i=0;i<m;i++){
57         scanf("%s%d%d",opt,&x,&y);
58         if(opt[0]==‘R‘){
59             w[++cnt].ps=x;
60             w[cnt].cl=y;
61             w[cnt].pre=las[x];
62             las[x]=y;
63         }
64         else{
65             e[++sz].L=x;
66             e[sz].R=y;
67             e[sz].id=sz;
68             e[sz].tm=cnt;
69         }
70     }
71
72     sort(e+1,e+1+sz,cmp);
73
74     for(int i=1;i<=sz;i++){
75         for(int j=e[i-1].tm+1;j<=e[i].tm;j++)
76             change(w[j].ps,w[j].cl);
77         for(int j=e[i-1].tm;j>=e[i].tm+1;j--)
78             change(w[j].ps,w[j].pre);
79
80         int l=e[i].L,r=e[i].R;
81         while(CL<l)  cala(CL++);
82         while(CL>l)  cala(--CL);
83         while(CR<r)  cala(++CR);
84         while(CR>r)  cala(CR--);
85
86         answer[e[i].id]=ans;
87     }
88
89     for(int i=1;i<=sz;i++)
90         printf("%d\n",answer[i]);
91     return 0;
92 }

时间: 2024-11-09 11:10:18

bzoj2120: 数颜色 [莫队][分块]的相关文章

bzoj2120 数颜色 莫队 带修改

[bzoj2120]数颜色 Description 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔. 2. R P Col 把第P支画笔替换为颜色Col.为了满足墨墨的要求,你知道你需要干什么了吗? Input 第1行两个整数N,M,分别代表初始画笔的数量以及墨墨会做的事情的个数.第2行N个整数,分别代表初始画笔排中第i支画笔的颜色.第3行到第2+M行,每行分

【国家集训队】 数颜色 - 莫队

题目描述 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会向你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔. 2. R P Col 把第P支画笔替换为颜色Col. 为了满足墨墨的要求,你知道你需要干什么了吗? 输入输出格式 输入格式: 第1行两个整数N,M,分别代表初始画笔的数量以及墨墨会做的事情的个数. 第2行N个整数,分别代表初始画笔排中第i支画笔的颜色. 第3行到第2+M行,每行分别代表墨墨会做的一件事

[Bzoj2120]数颜色 (非正解 )(莫队)

2120: 数颜色 Time Limit: 6 Sec  Memory Limit: 259 MBSubmit: 6286  Solved: 2489[Submit][Status][Discuss] Description 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔. 2. R P Col 把第P支画笔替换为颜色Col.为了满足墨墨的要求,你知道你需要干

莫队+分块 BZOJ 3809

3809: Gty的二逼妹子序列 Time Limit: 80 Sec  Memory Limit: 28 MBSubmit: 1634  Solved: 482[Submit][Status][Discuss] Description Autumn和Bakser又在研究Gty的妹子序列了!但他们遇到了一个难题. 对于一段妹子们,他们想让你帮忙求出这之内美丽度∈[a,b]的妹子的美丽度的种类数. 为了方便,我们规定妹子们的美丽度全都在[1,n]中. 给定一个长度为n(1<=n<=100000)

[BZOJ 3585] mex 【莫队+分块】

题目链接:BZOJ - 3585 题目分析 区间mex,即区间中没有出现的最小自然数. 那么我们使用一种莫队+分块的做法,使用莫队维护当前区间的每个数字的出现次数. 然后求mex用分块,将权值分块(显然mex 一定小于等于 n ,大于 n 的权值没有意义,可以直接忽略),每块大小 sqrt(n) . 然后区间中的某个数的数量被减到0的时候就将它所在的块的种类计数减一,添加数的时候类似. 然后枚举每个块,找到最小的中间有数不存在的块(即种类数小于块中的数的种数),然后到这个快里直接从小一个一个找到

HDU 5145 NPY and girls (莫队分块离线)

题目地址:HDU 5145 莫队真的好神奇..这样的复杂度居然只有n*sqrt(n)... 裸的莫队分块,先离线,然后按左端点分块,按块数作为第一关键字排序,然后按r值作为第二关键字进行排序.都是从小到大,可以证明这样的复杂度只有n*sqrt(n).然后进行块之间的转移. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <

BZOJ 4129 Haruna’s Breakfast 带修改树上莫队+分块

题目大意:给定一棵树,每个点有一个非负点权,支持下列操作 1.修改某个点的点权 2.查询某条链上的mex 考虑链上不带修改的版本,我们可以用莫队+分块来搞(链接戳这里) 现在到了树上带修改,果断糖果公园 本来抱着逗比的心态写了一发结果1.4s过了 跟糖果公园的80s完全不成正比啊0.0 #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <

BZOJ2120数颜色(带修改莫队)

2120: 数颜色 Time Limit: 6 Sec  Memory Limit: 259 MBSubmit: 7384  Solved: 2998[Submit][Status][Discuss] Description 墨 墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔. 2. R P Col 把第P支画笔替换为颜色Col.为了满足墨墨的要求,你知道你需要

[国家集训队][bzoj2120] 数颜色 [带修改莫队]

题面: 传送门 思路: 这道题和SDOI2009的HH的项链很像,只是多了一个修改 模板套上去呀 莫队学习请戳这里:莫队 Code: 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 inline int read(){ 8 int re=0,fla