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、莫队一般情况下是进行数据修改的。如果需要修改时,则在问题的二元组(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 数颜色(带修改的莫队算法)的更多相关文章

  1. 【BZOJ】2120: 数颜色 带修改的莫队算法

    [题意]给定n个数字,m次操作,每次询问区间不同数字的个数,或修改某个位置的数字.n,m<=10^4,ai<=10^6. [算法]带修改的莫队算法 [题解]对于询问(x,y,t),其中t是 ...

  2. BZOJ 2120: 数颜色 带修改的莫队算法 树状数组套主席树

    https://www.lydsy.com/JudgeOnline/problem.php?id=2120 标题里是两种不同的解法. 带修改的莫队和普通莫队比多了个修改操作,影响不大,但是注意一下细节 ...

  3. Luogu P1903 BZOJ 2120 数颜色 带修改的莫队

    https://www.luogu.org/problemnew/show/P1903 之前切过这道题,复习莫队再切一遍,不过我之前写的是主席树和树状数组,也不知道我当时怎么想的…… 这个题卡常我没写 ...

  4. BZOJ2120数颜色(带修改莫队)

    莫队算法是一种数据结构的根号复杂度替代品,主要应用在询问[l,r]到询问[l+1,r]和[l,r+1]这两个插入和删除操作复杂度都较低的情况下.具体思想是:如果把一个询问[l,r]看做平面上的点(l, ...

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

    题面: 传送门 思路: 这道题和SDOI2009的HH的项链很像,只是多了一个修改 模板套上去呀 莫队学习请戳这里:莫队 Code: #include<iostream> #include ...

  6. BZOJ 2120 数颜色&2453 维护队列 [带修改的莫队算法]【学习笔记】

    2120: 数颜色 Time Limit: 6 Sec  Memory Limit: 259 MBSubmit: 3665  Solved: 1422[Submit][Status][Discuss] ...

  7. P1903 [国家集训队]数颜色 (带修改莫队)

    题目描述 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会向你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔. 2 ...

  8. P1903 [国家集训队]数颜色 / 维护队列 带修改的莫队

    \(\color{#0066ff}{ 题目描述 }\) 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会向你发布如下指令: 1. Q L R代表询问你从第L支 ...

  9. bzoj2120 数颜色——带修莫队

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2120 带修改的莫队: 用结构体存下修改和询问,排好序保证时间后就全局移动修改即可: 参考了T ...

随机推荐

  1. 快速沃尔什变换 (FWT)学习笔记

    证明均来自xht37 的洛谷博客 作用 在 \(OI\) 中,\(FWT\) 是用于解决对下标进行位运算卷积问题的方法. \(c_{i}=\sum_{i=j \oplus k} a_{j} b_{k} ...

  2. [leetcode349]Intersection of Two Arrays

    设计的很烂的一道题 List<Integer> res = new ArrayList<>(); // int l1 = nums1.length; // int l2 = n ...

  3. 解决qt程序运行时的cannot create Qt for Embedded Linux data directory: /tmp/qtembedded-0

    方法1: 1.mkdir /tmp 2.挂载 mount -t tmpfs -o size=32m none /tmp 方法2: 上面的user 0h说明你是以root用户的身份运行.可以尝试切换一下 ...

  4. python 3.6 导入c++dll所遇到的坑

    1 返回值在c++里面为const char*,python 接收实际上为int类型 原因:python默认返回值为int 解决方法: import ctypes import os CUR_PATH ...

  5. 查找linux系统下的端口被占用进程的两种方法 【转】

    在linux下开发时,你的软件可能要使用某一个端口,或者想查找某一个端口是否被占用.需要怎么做呢??这的确是一个比较烦恼的问题,我也此为这个苦恼过.但是通过查找man手册,还是同事的交流.总结出来两种 ...

  6. VsCode通过SSH连接远程服务器开发

    前言 nil 正文 安装插件 安装VsCode官方插件 Remote - SSH Remote - SSH: Editing Configuration Files WSL(远程桌面连接需要Remot ...

  7. AndroidStuidio安装

    前言 端午小长假,安卓入门走起 正文 下载AndroidStudio 这里给出google的官网 https://developer.android.com/studio 注意,因404原因,如果你无 ...

  8. Spring Boot Security 国际化 多语言 i18n 趟过巨坑

    网上很多的spring boot国际化的文章都是正常情况下的使用方法 如果你像我一样用了Spring Security 那么在多语言的时候可能就会遇到一个深渊 Spring Security里面的异常 ...

  9. Java API 操作HBase Shell

    HBase Shell API 操作 创建工程 本实验的环境实在ubuntu18.04下完成,首先在改虚拟机中安装开发工具eclipse. 然后创建Java项目名字叫hbase-test 配置运行环境 ...

  10. Java并发编程实战(5)- 线程生命周期

    在这篇文章中,我们来聊一下线程的生命周期. 目录 概述 操作系统中的线程生命周期 Java中的线程生命周期 Java线程状态转换 运行状态和阻塞状态之间的转换 运行状态和无时限等待状态的切换 运行状态 ...