[CodeVS4919]线段树练习4
线段树。每个节点分别维护当前区间内%7分别等于0~6的数的个数,lazy tag记录当前区间增加的量,查询时将val“平移”lazy个即可。
1 #include<iostream> 2 #include<algorithm> 3 #define maxn 100001 4 #define root 1 5 #define _left <<1 6 #define _right <<1|1 7 int n; 8 class SegmentTree { 9 private: 10 int val[maxn<<2][7],lazy[maxn<<2]; 11 void push_up(const int p) { 12 for(int i=0;i<7;i++) { 13 val[p][i]=val[p _left][i]+val[p _right][i]; 14 } 15 } 16 void swap(const int p,const int q) { 17 if(!lazy[p]) return; 18 int t[7]; 19 for(int i=0;i<7;i++) t[(i+q)%7]=val[p][i]; 20 for(int i=0;i<7;i++) val[p][i]=t[i]; 21 } 22 void push_down(const int p) { 23 if(!lazy[p]) return; 24 lazy[p _left]=lazy[p _left]+lazy[p]; 25 lazy[p _right]=lazy[p _right]+lazy[p]; 26 swap(p _left,lazy[p]); 27 swap(p _right,lazy[p]); 28 lazy[p]=0; 29 } 30 public: 31 void build(const int p,const int b,const int e) { 32 lazy[p]=0; 33 if(b==e) { 34 int x; 35 std::cin>>x; 36 val[p][x%7]=1; 37 return; 38 } 39 int mid=(b+e)>>1; 40 build(p _left,b,mid); 41 build(p _right,mid+1,e); 42 push_up(p); 43 } 44 void modify(const int p,const int b,const int e,const int l,const int r,const int x) { 45 if(b!=e) push_down(p); 46 if((b==l)&&(e==r)) { 47 lazy[p]=lazy[p]+x; 48 swap(p,x); 49 return; 50 } 51 int mid=(b+e)>>1; 52 if(l<=mid) modify(p _left,b,mid,l,std::min(mid,r),x); 53 if(r>mid) modify(p _right,mid+1,e,std::max(mid+1,l),r,x); 54 push_up(p); 55 } 56 int query(const int p,const int b,const int e,const int l,const int r) { 57 if(b!=e) push_down(p); 58 if((b==l)&&(e==r)) { 59 return val[p][0]; 60 } 61 int mid=(b+e)>>1,ans=0; 62 if(l<=mid) ans+=query(p _left,b,mid,l,std::min(mid,r)); 63 if(r>mid) ans+=query(p _right,mid+1,e,std::max(mid+1,l),r); 64 return ans; 65 } 66 }; 67 SegmentTree tree; 68 int main() { 69 std::ios_base::sync_with_stdio(false); 70 std::cin>>n; 71 tree.build(root,1,n); 72 int q; 73 for(std::cin>>q;q--;) { 74 char op[6]; 75 std::cin>>op; 76 if(op[0]=='a') { 77 int x,y,k; 78 std::cin>>x>>y>>k; 79 tree.modify(root,1,n,x,y,k); 80 } 81 else { 82 int x,y; 83 std::cin>>x>>y; 84 std::cout<<tree.query(root,1,n,x,y)<<std::endl; 85 } 86 } 87 return 0; 88 }