数颜色 HYSBZ - 2120(带修改的莫队)

数颜色

HYSBZ - 2120

 

 

 1 //modify dodui
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <iostream>
 7 using namespace std;
 8 const int maxn = 10010;
 9 int n, m;
10 int pos[maxn];
11 struct Q{
12     int l, r, tim, id;
13     bool operator < (const Q &a)const{
14         return pos[l] == pos[a.l] ? r == a.r ? tim < a.tim : r < a.r : pos[l] < pos[a.l];
15     }
16 }q[maxn];
17 struct C{
18     int p, nw, od;
19 }c[maxn];
20 int l, r, t;
21 int tot, tim;
22 int cor[maxn], cp[maxn];
23 int res[maxn];
24 int num[maxn * 100];
25 int ans;
26 void update(int p, int v){
27     num[p] += v;
28     if(v == 1) ans += num[p] == 1;
29     else ans -= num[p] == 0;
30 }
31 void redo(int p, int temp){
32     if(l <= p && p <= r) {
33         update(cor[p], -1);
34         update(temp, 1);
35     }
36     cor[p] = temp;
37 
38 }
39 void solve(){
40     ans = 0;
41     for(int i = 1; i <= tot; i++){
42         while(t < q[i].tim) t++, redo(c[t].p, c[t].nw);
43         while(t > q[i].tim) redo(c[t].p, c[t].od), t--;
44 
45         while(l < q[i].l) update(cor[l], -1), l++;
46         while(l > q[i].l) l--, update(cor[l], 1);
47 
48         while(r > q[i].r) update(cor[r], -1), r--;
49         while(r < q[i].r) r++, update(cor[r], 1); 
50 
51         res[q[i].id] = ans;
52     }
53 }
54 
55 int main(){
56     while(scanf("%d %d", &n, &m) != EOF){
57         memset(num, 0, sizeof num);
58         int SZ = sqrt(n * 1.0);
59         for(int i = 1; i <= n; i++){
60             scanf("%d", &cor[i]);
61             cp[i] = cor[i];
62             pos[i] = (i - 1) / SZ + 1;
63         }
64         l = 1, r = 0, t = 0;
65         tot = 0, tim = 0;
66         char op[4];
67         int x, y;
68         for(int i = 0; i < m; i++){
69             scanf("%s %d %d", op, &x, &y);
70             if(op[0] == 'Q'){
71                 q[++tot] = Q{x, y, tim, tot};
72             }else{
73                 c[++tim] = C{x, y, cp[x]};
74                 cp[x] = y;
75             }
76         }
77         sort(q, q + tot);
78         solve();
79         for(int i = 1; i <= tot; i++) printf("%d\n", res[i]);
80     }
81     return 0;
82 }
View Code

 

转载于:https://www.cnblogs.com/yijiull/p/8351158.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值