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
1 2 3 4 5 5
Q 1 4
Q 2 6
R 1 2
Q 1 4
Q 2 6
Sample Output
4
3
4
HINT
对于100%的数据,N≤10000,M≤10000,修改操作不多于1000次,所有的输入数据中出现的所有整数均大于等于1且不超过10^6。
————————————————————————————————————————————————————————————————————————————————
1、莫队一般情况下是进行数据修改的。如果需要修改时,则在问题的二元组(l,r)中加入第三项pre,构成三元组(l,r,pre)。其中pre表示已经修改过几次。并在排序中加入第三关键字pre。
2、记录每一次更改,并记录每次更改前后的数据。当由一种询问变到另一种询问时,只要先将pre通过记录的更改变成下一次询问的pre,然后再按照一般莫队算法依次修改 l 和 r,得到最终结果 。
3、注意:
a、每次pre的修改,如果修改点在上次查询的范围内,则应当把把对应的ans进行修改。
b、每次修改都会对记录数组时行改变。但是查询的状态需要对应状态pre。
难懂!也就是在查询初始状态时(l=2,r=1)它对应还没有修改过的笔的状态;不能用改了某些笔的姿态来进行查询。
————————————————————————————————————————————————————————————————————————————————
1 #include<bits/stdc++.h>
2
3 using namespace std;
4 const int maxn=1e4+7;
5 int n,m,siz;
6 int cl[maxn],clf[maxn];
7 int clh[1000007];
8 char s[2];
9 struct que
10 {
11 int l,r,id,belong,chgd;
12 }q[maxn];
13 struct chang
14 {
15 int ps,pre,nex,id;
16 }ch[maxn];
17 int l,r,c,ans,da[maxn];
18
19 void readint(int &x)
20 {
21 char c=getchar();
22 int f=1;
23 for(;c>'9'||c<'0';c=getchar())if(c=='-')f=-f;
24 x=0;
25 for(;c<='9' && c>='0';c=getchar())x=(x<<1)+(x<<3)+c-'0';
26 x=x*f;
27 }
28 bool cmp(que a,que b)
29 {
30 if(a.belong<b.belong)return 1;
31 if(a.belong==b.belong &&a.r<b.r)return 1;
32 if(a.belong==b.belong &&a.r==b.r &&a.chgd<b.chgd)return 1;
33 return 0;
34 }
35 void del(int ps)
36 {
37 ps=clf[ps];
38 clh[ps]--;
39 if(clh[ps]==0)ans--;
40 }
41 void add(int ps)
42 {
43 ps=clf[ps];
44 clh[ps]++;
45 if(clh[ps]==1)ans++;
46 }
47 int main()
48 {
49 readint(n);readint(m);
50 for(int i=1;i<=n;i++)
51 {
52 readint(cl[i]);clf[i]=cl[i];
53 }
54 int bs=sqrt(n+0.5);
55 int cjs=0,qjs=0;
56 for(int a,b,i=0;i<m;i++)
57 {
58 scanf("%s",s);readint(a);readint(b);
59 if(s[0]=='Q')
60 {
61 q[qjs].l=a;q[qjs].r=b;
62 q[qjs].id=qjs;q[qjs].belong=(a-1)/bs;
63 q[qjs].chgd=cjs;
64 qjs++;
65 }
66 else
67 {
68 ch[cjs].id=cjs;
69 ch[cjs].ps=a;
70 ch[cjs].nex=b;
71 ch[cjs].pre=cl[a];
72 cl[a]=b;
73 cjs++;
74 }
75 }
76 sort(q,q+qjs,cmp);
77 l=2;r=1;ans=0;c=0;
78 for(int i=0;i<qjs;i++)
79 {
80 while(c<q[i].chgd)
81 {
82 if(ch[c].ps>=l && ch[c].ps<=r)
83 {
84 clh[ch[c].pre]--;
85 if(clh[ch[c].pre]==0)ans--;
86 clh[ch[c].nex]++;
87 if(clh[ch[c].nex]==1)ans++;
88 }
89 clf[ch[c].ps]=ch[c].nex;
90 c++;
91 }
92 while(c>q[i].chgd)
93 {
94 c--;
95 if(ch[c].ps>=l &&ch[c].ps<=r)
96 {
97 clh[ch[c].pre]++;
98 if(clh[ch[c].pre]==1)ans++;
99 clh[ch[c].nex]--;
100 if(clh[ch[c].nex]==0)ans--;
101 }
102 clf[ch[c].ps]=ch[c].pre;
103 }
104 while(l<q[i].l)
105 {
106 del(l);l++;
107 }
108 while(l>q[i].l)
109 {
110 l--;add(l);
111 }
112 while(r<q[i].r)
113 {
114 r++;add(r);
115 }
116 while(r>q[i].r)
117 {
118 del(r);r--;
119 }
120 da[q[i].id]=ans;
121 }
122 for(int i=0;i<qjs;i++)printf("%d\n",da[i]);
123 return 0;
124 }
BZOJ2120 数颜色(带修改的莫队算法)的更多相关文章
- 【BZOJ】2120: 数颜色 带修改的莫队算法
[题意]给定n个数字,m次操作,每次询问区间不同数字的个数,或修改某个位置的数字.n,m<=10^4,ai<=10^6. [算法]带修改的莫队算法 [题解]对于询问(x,y,t),其中t是 ...
- BZOJ 2120: 数颜色 带修改的莫队算法 树状数组套主席树
https://www.lydsy.com/JudgeOnline/problem.php?id=2120 标题里是两种不同的解法. 带修改的莫队和普通莫队比多了个修改操作,影响不大,但是注意一下细节 ...
- Luogu P1903 BZOJ 2120 数颜色 带修改的莫队
https://www.luogu.org/problemnew/show/P1903 之前切过这道题,复习莫队再切一遍,不过我之前写的是主席树和树状数组,也不知道我当时怎么想的…… 这个题卡常我没写 ...
- BZOJ2120数颜色(带修改莫队)
莫队算法是一种数据结构的根号复杂度替代品,主要应用在询问[l,r]到询问[l+1,r]和[l,r+1]这两个插入和删除操作复杂度都较低的情况下.具体思想是:如果把一个询问[l,r]看做平面上的点(l, ...
- [国家集训队][bzoj2120] 数颜色 [带修改莫队]
题面: 传送门 思路: 这道题和SDOI2009的HH的项链很像,只是多了一个修改 模板套上去呀 莫队学习请戳这里:莫队 Code: #include<iostream> #include ...
- BZOJ 2120 数颜色&2453 维护队列 [带修改的莫队算法]【学习笔记】
2120: 数颜色 Time Limit: 6 Sec Memory Limit: 259 MBSubmit: 3665 Solved: 1422[Submit][Status][Discuss] ...
- P1903 [国家集训队]数颜色 (带修改莫队)
题目描述 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会向你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔. 2 ...
- P1903 [国家集训队]数颜色 / 维护队列 带修改的莫队
\(\color{#0066ff}{ 题目描述 }\) 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会向你发布如下指令: 1. Q L R代表询问你从第L支 ...
- bzoj2120 数颜色——带修莫队
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2120 带修改的莫队: 用结构体存下修改和询问,排好序保证时间后就全局移动修改即可: 参考了T ...
随机推荐
- 这4种ThreadLocal你都知道吗?
什么是ThreadLocal ThreadLocal类顾名思义可以理解为线程本地变量.也就是说如果定义了一个ThreadLocal, 每个线程往这个ThreadLocal中读写是线程隔离,互相之间不会 ...
- 记一次jedis并发使用问题JedisException: Could not return the resource to the pool
今天线上突然发现个奇怪的问题项目第一次启动的时候redis报错JedisException: Could not return the resource to the pool 直接访问接口的时候不报 ...
- pyspark使用-dataframe操作
一.读取csv文件 1.用pandas读取 import pandas as pd from pyspark.sql import SparkSession spark=SparkSession.bu ...
- MongoDb学习(五)--Gridfs--上传下载
版本 <dependency> <groupId>org.springframework.data</groupId> <artifactId>spri ...
- volatile实现原理--为什么实现了可见性却不能保证原子性
本篇文章我们来解决一个问题 这也是面试面的比较多的问题,进阶阶段(高级)一般都会问到. volatile变量怎么保证可见性 为什么在并发情况下无法保证原子性? 比较懒了 摘了一段JVM原理的片段 ...
- 多媒体开发(4):在视频上显示文字或图片--ffmpeg命令
小白:我录了段视频,里面用的音乐是有版权的,而且快过期了,能把音乐去掉吗? 小程拿到视频后,一个快捷键打开命令终端,快速打下一行命令: ffmpeg -i 小白.flv -vcodec copy -a ...
- el-input限制只能输入数字(开发小记)
输入框中限制通常有三种处理方法 第一种:设置type属性(不推荐) 设置type属性为number,text等等,此方法输入框的后面会有不必要样式出现 <el-input type=" ...
- 风炫安全WEB安全学习第二十二节课 DOM型XSS讲解
风炫安全WEB安全学习第二十二节课 DOM型XSS讲解 Dom型XSS演示 通过Javascript,可以重构整个HTML文档,你可以添加.移除.改变或重排页面上的项目 要改变页面的某个东西,Java ...
- centos7 在虚拟机中装好后的网络连接问题
1.首先设置网卡连接方式:点"设置",在弹出的界面中点"网络",最后选择"连接方式"为"桥接网卡" 2.用Vim编辑器打 ...
- Serverless 如何应对 K8s 在离线场景下的资源供给诉求
本文整理自腾讯云云原生产品团队的专家产品经理韩沛在 Techo 开发者大会云原生专题的分享内容--Kubernetes 混部与弹性容器.本次分享主要分为三部分:基于 K8s 的应用混部.提升应用混部效 ...