UESTC-1259 昊昊爱运动 II
昊昊爱运动 II
Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others)
昊昊喜欢运动
他N天内会参加M种运动(每种运动用一个[1,m]的整数表示)
现在有Q个操作,操作描述如下
- 昊昊把第l天到第r天的运动全部换成了x(x∈[1,m])
- 问昊昊第l天到第r天参加了多少种不同的运动
Input
输入两个数N, M (1≤N≤105, 1≤M≤100);
输入N个数ai(ai∈[1,m])表示在第i天昊昊做了第ai类型的运动;
输入一个数Q(1≤Q≤105);
输入Q行 每行描述以下两种操作
- 形如
M l r x
,表示昊昊把第l天到第r天的运动全部换成了x(x∈[1,m]) - 形如
Q l r
,表示昊昊想知道他第l天到第r天参加了多少种不同的运动
Output
对于所有的Q操作,每一行输出一个数 表示昊昊在第l天到第r天一共做了多少种活动
Sample input and output
Sample Input | Sample Output |
---|---|
5 3 1 2 3 2 3 4 Q 1 4 Q 2 4 M 5 5 2 Q 1 5 |
3 2 3 |
Source
咦。。。
分析
这道题看上去像是Dynamic len(set(a[LR])),但是单点更新变成了区间更新,看上去不太好搞。
注意到m比较小,可以用更简单的方式来维护,线段树每个结点用bitset保存一下这m个数字的出现情况和更新标记就好了。
/********************************************************* * --------------Alfheim-------------- * * author AbyssalFish * **********************************************************/ #include<bits/stdc++.h> using namespace std; typedef long long ll; const int MAX_N = 1e5+5, MAX_M = 100+28; int N, M; int a[MAX_N]; #define para int o = 1, int l = 1, int r = N #define lo (o<<1) #define ro (o<<1|1) #define Tvar int md = (l+r)>>1; #define lsn lo,l,md #define rsn ro,md+1,r #define insd ql <= l && r <= qr const int ST_SIZE = 1<<18; int S[ST_SIZE]; bitset<MAX_M> E[ST_SIZE]; inline void sink(int o,int s) { E[o].reset(); E[o].set(S[o] = s); } void build(para) { if(l == r){ E[o].set(a[l]); } else { Tvar build(lsn); build(rsn); E[o] = E[lo] | E[ro]; } } inline void push_down(int o) { if(S[o]){ sink(lo,S[o]); sink(ro,S[o]); S[o] = 0; } } bitset<MAX_M> res; int ql,qr; void query(para) { if(insd){ res |= E[o]; } else { push_down(o); Tvar if(ql <= md) query(lsn); if(qr > md) query(rsn); } } int qval; void modify(para) { if(insd){ sink(o,qval); } else { push_down(o); Tvar if(ql <= md) modify(lsn); if(qr > md) modify(rsn); E[o] = E[lo] | E[ro]; } } //#define LOCAL int main() { #ifdef LOCAL freopen("data.txt","r",stdin); #endif scanf("%d%d",&N,&M); for(int i = 1; i <= N; i++) scanf("%d",a+i); build(); int Q; scanf("%d",&Q); char op[2]; while(Q--){ scanf("%s%d%d",op,&ql,&qr); if(*op == 'Q'){ res.reset(); query(); printf("%d\n", res.count()); } else { scanf("%d",&qval); modify(); } } return 0; }