[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 }

 

posted @ 2017-05-21 15:27  skylee03  阅读(101)  评论(0编辑  收藏  举报