zoukankan      html  css  js  c++  java
  • hdoj6562 Lovers(线段树)

    传送:http://acm.hdu.edu.cn/showproblem.php?pid=6562

    题意:有$n$个字符串,初始为空。$m$次操作,每次操作如下:

    1. $wrap  l,r,d$ 代表给区间$[l,r]$内的每个字符串前后都加上数字$d$,即串变为$ds_id$;

    2. $query  l,r$ 代表询问区间$[l,r]$内的和。

    数据范围:

      $1 le T le 5, 1 le n, m le 1e5, 1 le l le r le n.$

    分析:

    求区间和。(感觉是线段树,然后和学妹开始了漫漫路。可是没有树出来qaq

    线段树每个结点维护:区间和$sum$,前缀的增量$lazy1$,后缀的增量$lazy2$,更新的长度$lazylen$,以及区间数值的长度$len$。

    但是这里的更新长度和区间数值长度存储是表示为$10^k$,因为每次算贡献的时候这样方便计算,避免多次调用$pow$函数。

    //开始考虑每增加一个$x$对于区间的影响:假设对于区间$[l,r]$增加了$x$。

    对于前缀$lazy1$的影响:$lazy1=原有的更新长度lazylen*x+lazy1$

    对于后缀$lazy2$的影响:$lazy2=lazy2*10+x$

    对于区间和$sum$的影响:$sum=x*tree[root].len*10+(tree[root].r-tree[root].l+1)*x+tree[root].sum*10)$

    对于区间更新长度$lazylen$:$lazylen*=10$

    对于区间数值长度$len$:$len*=100$

    然后每次需要把更新下传给左右儿子,然后取消他本身的更新标记。

    每次$update$都需要$pushdown$和$pushup$。

    代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int maxn=2e5+10;
     5 const int mod=1e9+7;
     6 struct node{
     7     ll l,r,sum;
     8     ll lazylen,lazy1,lazy2,len;
     9 }tree[maxn<<2];
    10 ll ans;
    11 void pushup(int root){
    12     tree[root].len=(tree[root<<1].len+tree[root<<1|1].len)%mod;
    13     tree[root].sum=(tree[root<<1].sum+tree[root<<1|1].sum)%mod;
    14 }
    15 void build(int root,int l,int r){
    16     tree[root].l=l; tree[root].r=r;tree[root].sum=0;
    17     tree[root].lazylen=1; tree[root].lazy1=0;tree[root].lazy2=0;tree[root].len=0;
    18     if (l==r){
    19         tree[root].len=1;
    20         return ;
    21     }
    22     int mid=(l+r)>>1;
    23     build(root<<1,l,mid);
    24     build(root<<1|1,mid+1,r);
    25     pushup(root);
    26 }
    27 void pushdown(int root){
    28     if (tree[root].lazylen>1){
    29         tree[root<<1].lazy1=(tree[root<<1].lazylen*tree[root].lazy1+tree[root<<1].lazy1)%mod;
    30         tree[root<<1].lazy2=(tree[root<<1].lazy2*tree[root].lazylen+tree[root].lazy2)%mod;
    31         tree[root<<1|1].lazy1=(tree[root<<1|1].lazylen*tree[root].lazy1+tree[root<<1|1].lazy1)%mod;
    32         tree[root<<1|1].lazy2=(tree[root<<1|1].lazy2*tree[root].lazylen+tree[root].lazy2)%mod;
    33         
    34         tree[root<<1].sum=(tree[root].lazy1*tree[root<<1].len%mod*tree[root].lazylen%mod
    35             +(tree[root<<1].r-tree[root<<1].l+1)*tree[root].lazy2%mod+tree[root<<1].sum*tree[root].lazylen)%mod;
    36         tree[root<<1|1].sum=(tree[root].lazy1*tree[root<<1|1].len%mod*tree[root].lazylen%mod
    37             +(tree[root<<1|1].r-tree[root<<1|1].l+1)*tree[root].lazy2%mod+tree[root<<1|1].sum*tree[root].lazylen)%mod;
    38         
    39         tree[root<<1].len=(tree[root<<1].len*tree[root].lazylen%mod*tree[root].lazylen)%mod;
    40         tree[root<<1|1].len=(tree[root<<1|1].len*tree[root].lazylen%mod*tree[root].lazylen)%mod;
    41         
    42         tree[root<<1].lazylen=(tree[root<<1].lazylen*tree[root].lazylen)%mod;
    43         tree[root<<1|1].lazylen=(tree[root<<1|1].lazylen*tree[root].lazylen)%mod;
    44         
    45         tree[root].lazy1=0;tree[root].lazy2=0;tree[root].lazylen=1;
    46     }
    47 }
    48 
    49 void update(int root,int l,int r,int x){
    50     if (tree[root].l>=l && tree[root].r<=r){
    51         tree[root].sum=(x*tree[root].len*10%mod+(tree[root].r-tree[root].l+1)*x%mod+tree[root].sum*10)%mod;
    52         tree[root].len=(tree[root].len*100)%mod;
    53         
    54         tree[root].lazy1=(tree[root].lazylen*x+tree[root].lazy1)%mod;
    55         tree[root].lazy2=(tree[root].lazy2*10+x)%mod;
    56         tree[root].lazylen=tree[root].lazylen*10%mod;
    57         pushdown(root);
    58         return ;
    59     }
    60     pushdown(root);
    61     int mid=(tree[root].l+tree[root].r)>>1;
    62     if (mid>=l) update(root<<1,l,r,x);
    63     if (mid<r) update(root<<1|1,l,r,x);
    64     pushup(root);
    65 }
    66 void query(int root,int l,int r){
    67     if (tree[root].l>=l && tree[root].r<=r){
    68         (ans+=tree[root].sum)%=mod;
    69         return ;
    70     }
    71     pushdown(root);
    72     int mid=(tree[root].l+tree[root].r)>>1;
    73     if (mid>=l) query(root<<1,l,r);
    74     if (mid<r) query(root<<1|1,l,r);
    75 }
    76 int main(){
    77     int t,n,m,x,y,z,_=0; scanf("%d",&t);
    78     string s;
    79     while (t--){
    80         scanf("%d%d",&n,&m);
    81         build(1,1,n);
    82         printf("Case %d:
    ",++_);
    83         while (m--){
    84             cin >> s;
    85             if (s=="wrap"){
    86                 scanf("%d%d%d",&x,&y,&z);
    87                 update(1,x,y,z);
    88             }
    89             else{
    90                 scanf("%d%d",&x,&y);
    91                 ans=0;
    92                 query(1,x,y);
    93                 printf("%lld
    ",ans);
    94             }
    95         } 
    96     }
    97     return 0;
    98 }                                 
  • 相关阅读:
    JetBrains全家桶破解-Golang-Pycharm-IDEA等-不分平台
    k8s node update kernel
    k8s 图解
    k8s孤儿卷的问题
    k8s相关工作中常用命令
    AMQ死信引发宕机的问题
    StackStorm简介之actions
    DRF 使用入门
    python装饰器的简单实用
    type和object的关系
  • 原文地址:https://www.cnblogs.com/changer-qyz/p/11201188.html
Copyright © 2011-2022 走看看