博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ 2120 数颜色 【带修改莫队】
阅读量:4946 次
发布时间:2019-06-11

本文共 3448 字,大约阅读时间需要 11 分钟。

任意门:

2120: 数颜色

Time Limit: 6 Sec  Memory Limit: 259 MB
Submit: 10095  Solved: 4222
[][][]

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

 

 

解题思路:

单点更新,xjb查询,莫队或者分块。

但是莫队需要离线,这里需要修改,怎么办呢?

引入第三个参数记录时间,根据时间点的不同更新答案。

 

AC code:

1 #include 
2 #define INF 0x3f3f3f3f 3 #define LL long long 4 using namespace std; 5 const int MAXN = 1e4+10; 6 const int MAXM = 1e6+10; 7 int N, M; 8 int h[MAXN], num[MAXN]; 9 int ans[MAXN], sum[MAXM]; 10 struct Query 11 { 12 int l, r, id, t; 13 }Q[MAXN]; 14 15 struct Time 16 { 17 int ip, co, lt; 18 }t[MAXN]; 19 int last[MAXN]; 20 21 bool cmp(Query a, Query b) 22 { 23 if(h[a.l] != h[b.l]) return h[a.l] < h[b.l]; 24 else{ 25 if(h[a.r] != h[b.r]) return h[a.r] < h[b.r]; 26 else return a.t < b.t; 27 } 28 } 29 30 int update(int tt, int L, int R, int no) 31 { 32 int res = 0; 33 int x = t[tt].ip, val = t[tt].co, lst = t[tt].lt; 34 if(t[tt].ip >= L && t[tt].ip <= R){ 35 if(sum[num[x]] == 1) res--; 36 sum[num[x]]--; 37 if(no == 1){ 38 if(sum[val] == 0) res++; 39 sum[val]++; 40 } 41 else if(no == -1){ 42 if(sum[lst] == 0) res++; 43 sum[lst]++; 44 } 45 } 46 if(no == 1) num[x] = val; 47 else if(no == -1) num[x] = lst; 48 return res; 49 } 50 51 int add(int x, int val) 52 { 53 int res = 0; 54 if(val == 1 && sum[num[x]] == 0) res++; 55 if(val == -1 && sum[num[x]] == 1) res--; 56 sum[num[x]]+=val; 57 return res; 58 } 59 60 int main() 61 { 62 scanf("%d %d", &N, &M); 63 for(int i = 1; i <= N; i++){ 64 scanf("%d", &num[i]); 65 last[i] = num[i]; 66 } 67 int lim = pow(N, (double)2/3); 68 for(int i = 1; i <= N; i++) h[i] = (i-1)/lim+1; 69 int cnt = 0, Tcnt = 0; 70 char com[5]; 71 for(int i = 1; i <= M; i++){ 72 scanf("%s", com); 73 if(com[0] == 'Q'){ 74 cnt++; 75 scanf("%d %d", &Q[cnt].l, &Q[cnt].r); 76 Q[cnt].t = Tcnt; 77 Q[cnt].id = cnt; 78 } 79 else{ 80 Tcnt++; 81 scanf("%d %d", &t[Tcnt].ip, &t[Tcnt].co); 82 t[Tcnt].lt = last[t[Tcnt].ip]; 83 last[t[Tcnt].ip] = t[Tcnt].co; 84 //printf("%d %d\n", t[Tcnt].co, t[Tcnt].lt); 85 } 86 } 87 sort(Q+1, Q+1+cnt, cmp); 88 89 int L = 1, R = 0, T = 0, cur = 0; 90 for(int i = 1; i <= cnt; i++){ 91 while(T < Q[i].t) cur+=update(++T, L, R, 1); 92 while(T > Q[i].t) cur+=update(T--, L, R, -1); 93 while(L < Q[i].l) cur+=add(L++, -1); 94 while(L > Q[i].l) cur+=add(--L, 1); 95 while(R < Q[i].r) cur+=add(++R, 1); 96 while(R > Q[i].r) cur+=add(R--, -1); 97 ans[Q[i].id] = cur; 98 } 99 100 for(int i = 1; i <= cnt; i++){101 printf("%d\n", ans[i]);102 }103 104 return 0;105 106 }

 

转载于:https://www.cnblogs.com/ymzjj/p/10412032.html

你可能感兴趣的文章
【TP SRM 703 div2 500】 GCDGraph
查看>>
hdu1203 dp背包问题
查看>>
Ubuntu grub2的修复
查看>>
ASP.NET 2.0: 在使用web.sitemap时,如何实现本地化
查看>>
MapReduce 重要组件——Recordreader组件 [转]
查看>>
2017-2018-2 20179225 《密码与安全新技术专题》 第6周作业
查看>>
转载:Linux命令行快捷键
查看>>
多个viewpager可能产生的问题
查看>>
webdriver api
查看>>
转载-FileZilla Server源码分析(1)
查看>>
apache 实现图标缓存客户端
查看>>
MediaWiki左侧导航栏通过特殊页面就可以设置。
查看>>
html基础之DOM操作
查看>>
几种图表库
查看>>
揭秘:黑客必备的Kali Linux是什么,有哪些弊端?
查看>>
linux系统的远程控制方法——学神IT教育
查看>>
springboot+mybatis报错Invalid bound statement (not found)
查看>>
Linux环境下SolrCloud集群环境搭建关键步骤
查看>>
SPARK安装一:Windows下VirtualBox安装CentOS
查看>>
P3565 [POI2014]HOT-Hotels
查看>>