2018湘潭大学程序设计竞赛【H】
题目链接:https://www.nowcoder.com/acm/contest/105/H
题意:两个操作,一个在[l,r]区间放颜色为c的球,一个统计在[l,r]里有多少不同颜色的球。
题解:哎,线段树嘛。板子嘛、把求和操作改一改嘛。当时没用lazy操作T了嘛。谢谢大佬的板子。小萌新知道lazy是个啥玩意儿了。emmm..最后统计一下1的个数就是答案啦。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 using namespace std; 5 #define ll long long 6 struct data{ 7 int l,r; 8 ll add; 9 ll sum; 10 }data[400005]; 11 12 void build(int l,int r,int k){ 13 data[k].l=l; 14 data[k].r=r; 15 data[k].add=0; 16 data[k].sum=0; 17 if(l==r){ 18 return ; 19 } 20 int mid=(data[k].l+data[k].r) >> 1; 21 build(l,mid,k*2); 22 build(mid+1,r,k*2+1); 23 } 24 25 void pushdown(int k){ 26 if(data[k].add==0) return ; 27 data[k*2].sum |= data[k].add; 28 data[k*2+1].sum |= data[k].add; 29 data[k*2].add |= data[k].add; 30 data[k*2+1].add |=data[k].add; 31 data[k].add=0; 32 } 33 34 void update(int l,int r,int x,int k){ 35 if(data[k].l==l&&data[k].r==r){ 36 data[k].sum|=(ll)(1LL<<x); 37 data[k].add|=(ll)(1LL<<x); 38 return ; 39 } 40 pushdown(k); 41 int mid=(data[k].l + data[k].r)/2; 42 if(r <= mid){ 43 update(l,r,x,k*2); 44 }else if(l > mid){ 45 update(l,r,x,k*2+1); 46 }else{ 47 update(l,mid,x,k*2); 48 update(mid+1,r,x,k*2+1); 49 } 50 data[k].sum=data[k*2].sum | data[k*2+1].sum; 51 } 52 53 54 ll query(int l,int r,int k){ 55 if(data[k].l==l&&data[k].r==r){ 56 return data[k].sum; 57 } 58 pushdown(k); 59 int mid=(data[k].l + data[k].r) / 2; 60 if(r <= mid){ 61 return query(l,r,k*2); 62 }else if(l > mid){ 63 return query(l,r,k*2+1); 64 }else{ 65 return query(l,mid,k*2) | query(mid+1,r,k*2+1); 66 } 67 } 68 69 int main(){ 70 int n,m; 71 scanf("%d %d",&n,&m); 72 build(1,n,1); 73 while(m--){ 74 int flag; 75 scanf("%d",&flag); 76 if(flag==1){ 77 int x,y,k; 78 scanf("%d%d%d",&x,&y,&k); 79 update(x,y,k,1); 80 }else{ 81 int x,y; 82 scanf("%d%d",&x,&y); 83 int ans = query(x,y,1); 84 int cnt = 0; 85 while(ans){ 86 if(ans&1) 87 cnt++; 88 ans = ans >> 1; 89 } 90 cout<<cnt<<endl; 91 } 92 } 93 return 0; 94 }