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

    转载于:https://www.cnblogs.com/skylee03/p/6884996.html

  • 相关阅读:
    Chapter 7 Integrity(完整性), Views(视图), Security(安全性), and Catalogs(目录)
    Qt计时器
    linux命令:linux文件处理命令
    JSON.stringify()的不常见用法
    flex知识点归纳
    css伪类
    开发资源汇总
    Math.cbrt() Math.sqrt() Math.pow()
    代码开发注意事项和规范
    关于数组数据容易忽略的点
  • 原文地址:https://www.cnblogs.com/twodog/p/12140502.html
Copyright © 2020-2023  润新知