地址:http://acm.uestc.edu.cn/#/contest/show/95
题目:
Q - 昊昊爱运动 II
Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others)
昊昊喜欢运动
他NN 天内会参加MM 种运动(每种运动用一个[1,m][1,m] 的整数表示)
现在有QQ 个操作,操作描述如下
- 昊昊把第ll 天到第rr 天的运动全部换成了xx (x∈[1,m]x∈[1,m] )
- 问昊昊第ll 天到第rr 天参加了多少种不同的运动
Input
输入两个数NN , MM (1≤N≤1051≤N≤105 , 1≤M≤1001≤M≤100 );
输入NN 个数aiai (ai∈[1,m]ai∈[1,m] )表示在第i天昊昊做了第aiai 类型的运动;
输入一个数QQ (1≤Q≤1051≤Q≤105 );
输入QQ 行 每行描述以下两种操作
- 形如
M l r x
,表示昊昊把第ll 天到第rr 天的运动全部换成了xx (x∈[1,m]x∈[1,m] ) - 形如
Q l r
,表示昊昊想知道他第ll 天到第rr 天参加了多少种不同的运动
Output
lSample 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 |
思路:
区间覆盖,区间查询
依旧线段树搞起,不过有pushup和pushdown操作,这要注意下
具体的就不说了,和前面的题目没啥区别
对了要用bitset记录,,差点忘了、
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <algorithm> 3 #include <cstdio> 4 #include <cmath> 5 #include <cstring> 6 #include <queue> 7 #include <stack> 8 #include <map> 9 #include <vector> 10 #include <cstdlib> 11 #include <string> 12 #include <bitset> 13 14 #define PI acos((double)-1) 15 #define E exp(double(1)) 16 #define K 100000 17 using namespace std; 18 int n,m; 19 int a[K+5]; 20 struct node 21 { 22 bitset<110>s; 23 int change,l,r; 24 }; 25 struct node tree[4*K+5]; 26 27 void pushdown(int id) 28 { 29 if(!tree[id].change) 30 return ; 31 tree[id*2+1].s=tree[id*2].s=tree[id].s; 32 tree[id*2+1].change=tree[id*2].change=1; 33 tree[id].change=0; 34 } 35 void build(int id,int l,int r) 36 { 37 tree[id].l=l;tree[id].r=r;tree[id].change=0; 38 if(l==r) 39 tree[id].s[a[l]]=1; 40 else 41 { 42 int mid=(tree[id].l+tree[id].r)>>1; 43 if(r <= mid) build(id*2,l,r); 44 else if(l > mid) build(id*2+1,l,r); 45 else 46 { 47 build(id<<1,l,mid); 48 build(id*2+1,mid+1,r); 49 } 50 tree[id].s=tree[id*2].s|tree[id*2+1].s; 51 } 52 } 53 void update(int id,int l,int r,int v) 54 { 55 if(tree[id].l==l && tree[id].r==r) 56 { 57 tree[id].change=1; 58 tree[id].s.reset(); 59 tree[id].s[v]=1; 60 } 61 else 62 { 63 pushdown(id); 64 int mid=(tree[id].l+tree[id].r)>>1; 65 if(r<=mid) update(id<<1,l,r,v); 66 else if(l>mid) update(id*2+1,l,r,v); 67 else 68 { 69 update(id<<1,l,mid,v); 70 update(id*2+1,mid+1,r,v); 71 } 72 tree[id].s=tree[id*2].s|tree[id*2+1].s; 73 } 74 } 75 76 bitset<110> query(int id,int l,int r) 77 { 78 if(tree[id].l == l && tree[id].r==r ) 79 return tree[id].s; 80 else 81 { 82 pushdown(id); 83 int mid=(tree[id].l+tree[id].r)>>1; 84 bitset<110>ret; 85 if(r<=mid) ret=ret|query(id*2,l,r); 86 else if(l>mid) ret=ret|query(id*2+1,l,r); 87 else 88 { 89 ret=ret|query(id*2,l,mid); 90 ret=ret|query(id*2+1,mid+1,r); 91 } 92 return ret; 93 } 94 } 95 int main(void) 96 { 97 cin>>n>>m; 98 for(int i=1;i<=n;i++) 99 scanf("%d",&a[i]); 100 build(1,1,n); 101 int q; 102 cin>>q; 103 while(q--) 104 { 105 char c; 106 c=getchar(); 107 while(c==' ' || c==' ') 108 c=getchar(); 109 if(c=='M') 110 { 111 int l,r,v; 112 scanf("%d%d%d",&l,&r,&v); 113 update(1,l,r,v); 114 } 115 else 116 { 117 int l,r,num=0; 118 scanf("%d%d",&l,&r); 119 bitset<110> temp=query(1,l,r); 120 for(int i=1;i<=m;i++) 121 if(temp.test(i)) 122 num++; 123 printf("%d ",num); 124 } 125 } 126 return 0; 127 }