P1903 [国家集训队]数颜色 / 维护队列 (带修莫队)
作者:互联网
题目描述
墨墨购买了一套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支画笔中共有几种不同颜色的画笔。
输入输出样例
输入 #16 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
说明/提示
对于30%的数据,n,m \leq 10000n,m≤10000
对于60%的数据,n,m \leq 50000n,m≤50000
对于所有数据,n,m \leq 133333n,m≤133333
所有的输入数据中出现的所有整数均大于等于1且不超过10^6。
本题可能轻微卡常数
因为某些nt操作导致改了一天的bug, 所以记录一下 (不仔细读题的下场
排序条件尽量用三元表达式, 避免使用if else if, 后者花的时间很可能是不可接受的
举个例子, 上面是三元表达式排序, 下面是if else if判断排序, 时间差距甚至达到了一倍甚至更多
1 #include <iostream> 2 #include <algorithm> 3 #include <climits> 4 #include <cmath> 5 using namespace std; 6 constexpr int MAXN = 2e6 + 7, MAXM = 2e6 + 7, inf = 0x3f3f3f3f; 7 typedef long long ll; 8 int Block_Size, n, m; 9 int a[MAXN], id[MAXN], color[MAXN], ans[MAXN], res, qc, mc, ls = 1, rs; 10 11 inline int read() 12 { 13 char c = getchar(); 14 int x = 0, f = 1; 15 while (c < '0' || c > '9') 16 { 17 if (c == '-') 18 f = -1; 19 c = getchar(); 20 } 21 while (c >= '0' && c <= '9') 22 { 23 x = x * 10 + c - '0', c = getchar(); 24 } 25 return x * f; 26 } 27 struct query 28 { 29 int l; 30 int r; 31 int qid; 32 int time; 33 query(int l = 0, int r = 0, int qid = 0, int time = 0) : l(l), r(r), qid(qid), time(time) 34 { 35 } 36 37 bool operator<(const query &other) const 38 { 39 //一定要避免使用if else if的形式!!!! 40 //例如下面的写法 41 42 return id[l] == id[other.l] ? id[r] == id[other.r] ? time < other.time : r < other.r : l < other.l; 43 // if (id[l] == id[other.l]) 44 // { 45 // if (id[r] == id[other.r]) 46 // return l < other.l; 47 // return r < other.r; 48 // } 49 // return time < other.time; 50 } 51 } q[MAXM]; 52 53 struct modify 54 { 55 int pos; 56 int val; 57 modify(int pos = 0, int val = 0) : pos(pos), val(val) 58 { 59 } 60 } mod[MAXM]; 61 62 void del(int val) 63 { 64 if (--color[val] == 0) 65 --res; 66 } 67 68 void add(int val) 69 { 70 if (++color[val] == 1) 71 ++res; 72 } 73 74 void update(int x, int i) 75 { 76 if (q[i].l <= mod[x].pos && mod[x].pos <= q[i].r) 77 { 78 del(a[mod[x].pos]); 79 add(mod[x].val); 80 } 81 swap(a[mod[x].pos], mod[x].val); 82 } 83 84 int main() 85 { 86 char op; 87 int l, r, now = 0; 88 n = read(); 89 m = read(); 90 Block_Size = pow(n, 2.0 / 3.0); 91 for (int i = 1; i <= n; ++i) 92 { 93 a[i] = read(); 94 id[i] = (i - 1) / Block_Size; 95 } 96 97 for (int i = 1; i <= m; ++i) 98 { 99 scanf("%c", &op); 100 l = read(); 101 r = read(); 102 if (op == 'R') 103 { 104 ++mc; 105 mod[mc].pos = l; 106 mod[mc].val = r; 107 } 108 else 109 { 110 ++qc; 111 q[qc].l = l; 112 q[qc].r = r; 113 q[qc].time = mc; 114 q[qc].qid = qc; 115 } 116 } 117 sort(q + 1, q + qc + 1); 118 119 for (int i = 1; i <= qc; ++i) 120 { 121 while (ls < q[i].l) 122 del(a[ls++]); 123 while (ls > q[i].l) 124 add(a[--ls]); 125 126 while (rs < q[i].r) 127 add(a[++rs]); 128 while (rs > q[i].r) 129 del(a[rs--]); 130 131 while (now < q[i].time) 132 update(++now, i); 133 while (now > q[i].time) 134 update(now--, i); 135 136 ans[q[i].qid] = res; 137 } 138 139 for (int i = 1; i <= qc; ++i) 140 { 141 printf("%d\n", ans[i]); 142 } 143 144 return 0; 145 }AC code
标签:画笔,int,rs,P1903,while,MAXN,now,国家集训队,修莫队 来源: https://www.cnblogs.com/daremo/p/15367838.html