HDU6562 Lovers(线段树)

线段树题目,维护的信息非常对。

因为我们看到的是区间修改和区间查询,所以可以想到用线段树

现在的要求是往前后插数,求的是数的和。

因此我们可以考虑维护lazy标记往前插的数,往后插的数,和插的位数

并且还要维护答案sum1,以及区间的长度sum2,这是因为区间的长度是不定的,而我们维护区间和的时候,需要乘以区间长度,这个区间长度用10的次方表示

之后就是复杂的讨论,原理很简单,就是右移操作拼接真实的数

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
const int mod=1e9+7;
struct node{
    int l,r;
    ll sum1;
    ll sum2;
    ll lazy1;
    ll lazy2;
    ll lazy3;
    int st;
}tr[N<<2];
void pushup(int u){
    tr[u].sum1=(tr[u<<1].sum1+tr[u<<1|1].sum1)%mod;
    tr[u].sum2=(tr[u<<1].sum2+tr[u<<1|1].sum2)%mod;
}
void build(int u,int l,int r){
    if(l==r){
        tr[u]={l,r,0,1,0,0,1,0};
    }
    else{
        tr[u]={l,r,0,0,0,0,1,0};
        int mid=l+r>>1;
        build(u<<1,l,mid);
        build(u<<1|1,mid+1,r);
        pushup(u);
    }
}
void pushdown(int u){
    tr[u].st=0;
    ll x=tr[u].lazy1,y=tr[u].lazy2,z=tr[u].lazy3;
    tr[u].lazy1=tr[u].lazy2=0,tr[u].lazy3=1;
    tr[u<<1].st=tr[u<<1|1].st=1;
    tr[u<<1].lazy1=(tr[u<<1].lazy3*x%mod+tr[u<<1].lazy1)%mod;
    tr[u<<1|1].lazy1=(tr[u<<1|1].lazy3*x%mod+tr[u<<1|1].lazy1)%mod;
    tr[u<<1].lazy2=(z*tr[u<<1].lazy2+y)%mod;
    tr[u<<1|1].lazy2=(z*tr[u<<1|1].lazy2+y)%mod;
    tr[u<<1].lazy3=tr[u<<1].lazy3*z%mod;
    tr[u<<1|1].lazy3=tr[u<<1|1].lazy3*z%mod;
    tr[u<<1].sum1=(z*(tr[u<<1].sum2*x%mod+tr[u<<1].sum1)+(tr[u<<1].r-tr[u<<1].l+1)*y%mod)%mod;
    tr[u<<1|1].sum1=(z*(tr[u<<1|1].sum2*x%mod+tr[u<<1|1].sum1)+(tr[u<<1|1].r-tr[u<<1|1].l+1)*y%mod)%mod;
    tr[u<<1].sum2=tr[u<<1].sum2*z%mod*z%mod;
    tr[u<<1|1].sum2=tr[u<<1|1].sum2*z%mod*z%mod;
}
void modify(int u,int l,int r,int x){
    if(tr[u].l>=l&&tr[u].r<=r){
        tr[u].st=1;
        tr[u].lazy2=(10*tr[u].lazy2+x)%mod;
        tr[u].lazy1=(tr[u].lazy1+x*tr[u].lazy3%mod)%mod;
        tr[u].lazy3=10*tr[u].lazy3%mod;
        tr[u].sum1=(10*(tr[u].sum2*x+tr[u].sum1)+(tr[u].r-tr[u].l+1)*x)%mod;
        tr[u].sum2=100*tr[u].sum2%mod;
        return ;
    }
    if(tr[u].st){
        pushdown(u);
    }
    int mid=tr[u].l+tr[u].r>>1;
    if(l<=mid)
        modify(u<<1,l,r,x);
    if(r>mid)
        modify(u<<1|1,l,r,x);
    pushup(u);
}
int query(int u,int l,int r){
    if(tr[u].l>=l&&tr[u].r<=r){
        return tr[u].sum1;
    }
    if(tr[u].st){
        pushdown(u);
    }
    int mid=tr[u].l+tr[u].r>>1;
    ll ans=0;
    if(l<=mid)
        ans=query(u<<1,l,r);
    if(r>mid)
        ans=(ans+query(u<<1|1,l,r))%mod;
    return ans;
}
int main(){
    ios::sync_with_stdio(false);
    int t;
    cin>>t;
    int cnt=0;
    while(t--){
        int n,m;
        cin>>n>>m;
        int i;
        cnt++;
        build(1,1,n);
        cout<<"Case "<<cnt<<":"<<endl;
        while(m--){
            string s;
            cin>>s;
            if(s=="wrap"){
                int l,r,x;
                cin>>l>>r>>x;
                modify(1,l,r,x);
            }
            else{
                int l,r;
                cin>>l>>r;
                cout<<query(1,l,r)<<endl;
            }
        }
    }
    return 0;
}
View Code

 

posted @ 2020-10-24 12:49  朝暮不思  阅读(92)  评论(0编辑  收藏  举报