zoukankan      html  css  js  c++  java
  • 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
    没有人不辛苦,只有人不喊疼
  • 相关阅读:
    203. Remove Linked List Elements
    86. Partition List
    143. Reorder List
    876. Middle of the Linked List
    246. Strobogrammatic Number
    202. Happy Number
    数据类型转换
    表达式
    面向对象
    对齐
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/13868457.html
Copyright © 2011-2022 走看看