HDU 6562 Lovers(线段树)

参考:https://blog.csdn.net/qq_31411163/article/details/96345031
题意:给定n个空串,2种操作。把l r上的数前后都加上x;查询l r上数之和。
题解:维护sum1 sum2,以及左右标记和长度标记。维护过程详见代码。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define lson rt<<1
#define rson rt<<1|1
const int maxn=100010;
const int mod=1e9+7;

ll sum1[maxn<<2];//mark sum of a[i](l<=i<=r)
ll sum2[maxn<<2];//mark sum of 10^(len(a[i]))(l<=i<=r)
ll lazy1[maxn<<2];//左标记
ll lazy2[maxn<<2];//右标记
ll lazy3[maxn<<2];//长度标记
int n,m;

/*
sum1[rt]=(sum1[lson]+sum1[rson])
sum2[rt]=(sum2[lson]+sum2[rson])
*/
void pushup(int rt){
    sum1[rt]=(sum1[lson]+sum1[rson])%mod;
    sum2[rt]=(sum2[lson]+sum2[rson])%mod;
    return;
}
/*
sum1[lson]=sum1[lson]*lazy3[rt]+lazy2[rt]*(m-l+1)+lazy1[rt]*sum2[lson]*lazy3[rt];
sum1[rson]=sum1[rson]*lazy3[rt]+lazy2[rt]*(r-m)+lazy1[rt]*sum2[rson]*lazy3[rt];
sum2[lson]=sum2[lson]*lazy3[rt]*lazy3[rt];//
sum2[rson]=sum2[rson]*lazy3[rt]*lazy3[rt];//
lazy1[lson]=lazy1[lson]+lazy1[rt]*lazy3[lson];
lazy2[lson]=lazy2[lson]*lazy3[rt]+lazy2[rt];
lazy3[lson]=lazy3[lson]*lazy3[rt];
lazy1[rson]=lazy1[rson]+lazy1[rt]*lazy3[rson];
lazy2[rson]=lazy2[rson]*lazy3[rt]+lazy2[rt];
lazy3[rson]=lazy3[rson]*lazy3[rt];
lazy1[rt]=lazy2[rt]=0;
lazy3[rt]=1;
*/
void pushdown(int rt,int l,int r){
    if(lazy3[rt]==1) return;
    int m=(l+r)>>1;
    ll x=lazy1[rt],y=lazy2[rt],z=lazy3[rt];
    sum1[lson]=((sum1[lson]*z%mod+y*(m-l+1)%mod)%mod+x*sum2[lson]%mod*z%mod)%mod;
    sum1[rson]=((sum1[rson]*z%mod+y*(r-m)%mod)%mod+x*sum2[rson]%mod*z%mod)%mod;
    sum2[lson]=sum2[lson]*z%mod*z%mod;//
    sum2[rson]=sum2[rson]*z%mod*z%mod;//
    lazy1[lson]=(lazy1[lson]+x*lazy3[lson]%mod)%mod;
    lazy1[rson]=(lazy1[rson]+x*lazy3[rson]%mod)%mod;
    lazy2[lson]=(lazy2[lson]*z%mod+y)%mod;
    lazy2[rson]=(lazy2[rson]*z%mod+y)%mod;
    lazy3[lson]=lazy3[lson]*z%mod;
    lazy3[rson]=lazy3[rson]*z%mod;
    lazy1[rt]=lazy2[rt]=0;
    lazy3[rt]=1;
}

void build(int rt,int l,int r){
    //一开始把lazy标记放l r里面了,debug了5小时。。太久没碰线段树的后果么
    lazy1[rt]=0;lazy2[rt]=0;
    lazy3[rt]=1;
    if(l==r){
        sum1[rt]=0;sum2[rt]=1;
        return;
    }
    int m=(l+r)>>1;
    build(lson,l,m);
    build(rson,m+1,r);
    pushup(rt);
}



/*
sum1=sum1*10+sum2*val*10+val*(r-l+1)
sum2=sum2*100
lazy2=lazy2*10+val
lazy1=lazy1+lazy3*val
lazy3=lazy3*10
*/
void update(int rt,int l,int r,int a,int b,int val){
    if(l>=a&&r<=b){
        sum1[rt]=(sum1[rt]*10%mod+sum2[rt]*val%mod*10%mod+val*(r-l+1)%mod);
        sum2[rt]=sum2[rt]*100%mod;
        lazy2[rt]=(lazy2[rt]*10%mod+val)%mod;
        lazy1[rt]=(lazy1[rt]+lazy3[rt]*val%mod)%mod;
        lazy3[rt]=lazy3[rt]*10%mod;
        return;
    }
    pushdown(rt,l,r);
    int m=(l+r)>>1;
    if(a<=m) update(lson,l,m,a,b,val);
    if(m<b) update(rson,m+1,r,a,b,val);
    pushup(rt);
}
ll query(int rt,int l,int r,int a,int b){
    if(l>=a&&r<=b) return sum1[rt];
    pushdown(rt,l,r);
    int m=(l+r)>>1;
    ll ans=0;
    if(a<=m) ans=query(lson,l,m,a,b);
    if(m<b) ans=(ans+query(rson,m+1,r,a,b))%mod;
    return ans;
}

int main(){
    int t;scanf("%d",&t);
    int cas=1;
    while(t--){
        scanf("%d%d",&n,&m);
        build(1,1,n);
        int l,r,val;
        char s[10];
        printf("Case %d:\n",cas++);
        for(int i=1;i<=m;i++){
            scanf("%s%d%d",s,&l,&r);
            if(s[0]=='q'){
                ll ans;
                ans=query(1,1,n,l,r);
               //ans=query2(1,1,n,l,r);
                printf("%I64d\n",ans);
            }else{
                scanf("%d",&val);
                update(1,1,n,l,r,val);
                //update2(1,1,n,l,r,val);
            }
        }
    }
    return 0;
}

发布了71 篇原创文章 · 获赞 1 · 访问量 2830

猜你喜欢

转载自blog.csdn.net/weixin_43918473/article/details/103007633