• hdu4578 (多标记线段树)


    题意

    对于一个区间有4个操作:
    1.将a~b都加上c
    2.将a~b都乘上c
    3.将a~b都变成c
    4.查询a~b的每个数的p次方的和。(p=1,2,3)

    思路

    平方和这样来推:((a+c)^2=a^2+2ac+c^2)
    (sum2[rt] = sum2[rt] +2*sum1[rt] * c+(r-l+1)*c*c)
    立方和这样推:((a+c)^3=a^3+3a^2c+3ac^2+c^3)
    (sum3[rt]=sum3[rt]+3*sum2[rt]*c+3*sum1[rt]*c*c+(r-l+1)*c*c*c)
    注意懒惰数组下传的先后顺序

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int maxx = 1e5+10;
    const int mod = 10007;
    int t[maxx<<2][4],lazy[maxx<<2][4];
    void build(int l,int r,int rt)
    {
        lazy[rt][1]=1,lazy[rt][2]=0,lazy[rt][3]=0;
        for(int i=1;i<=3;i++)t[rt][i]=0;
        if(l==r)return;
        int mid=(l+r)/2;
        build(l,mid,rt*2);
        build(mid+1,r,rt*2+1);
    }
    void pushdown(int l,int r,int rt)
    {
        if(lazy[rt][3])
        {
            LL c=lazy[rt][3];
            t[rt*2][1]=c*l%mod;
            t[rt*2+1][1]=c*r%mod;
            t[rt*2][2]=c*c%mod*l%mod;
            t[rt*2+1][2]=c*c%mod*r%mod;
            t[rt*2][3]=c*c%mod*c%mod*l%mod;
            t[rt*2+1][3]=c*c%mod*c%mod*r%mod;
            lazy[rt*2][1]=lazy[rt*2+1][1]=1;
            lazy[rt*2][2]=lazy[rt*2+1][2]=0;
            lazy[rt*2][3]=lazy[rt*2+1][3]=c;
            lazy[rt][3]=0;
        }
        if(lazy[rt][1]!=1)
        {
            LL c=lazy[rt][1];
            t[rt*2][3]=t[rt*2][3]*c%mod*c%mod*c%mod;
            t[rt*2+1][3]=t[rt*2+1][3]*c%mod*c%mod*c%mod;
            t[rt*2][2]=t[rt*2][2]*c%mod*c%mod;
            t[rt*2+1][2]=t[rt*2+1][2]*c%mod*c%mod;
            t[rt*2][1]=t[rt*2][1]*c%mod;
            t[rt*2+1][1]=t[rt*2+1][1]*c%mod;
            lazy[rt*2][1]=lazy[rt*2][1]*c%mod;
            lazy[rt*2+1][1]=lazy[rt*2+1][1]*c%mod;
            lazy[rt*2][2]=lazy[rt*2][2]*c%mod;
            lazy[rt*2+1][2]=lazy[rt*2+1][2]*c%mod;
            lazy[rt][1]=1;
        }
        if(lazy[rt][2])
        {
            LL c=lazy[rt][2];
            t[rt*2][3]=(t[rt*2][3]+3*t[rt*2][2]*c%mod+3*t[rt*2][1]*c%mod*c%mod+c*c%mod*c%mod*l%mod)%mod;
            t[rt*2+1][3]=(t[rt*2+1][3]+3*t[rt*2+1][2]*c%mod+3*t[rt*2+1][1]*c%mod*c%mod+c*c%mod*c%mod*r%mod)%mod;
            t[rt*2][2]=(t[rt*2][2]+2*t[rt*2][1]*c%mod+c*c%mod*l%mod)%mod;
            t[rt*2+1][2]=(t[rt*2+1][2]+2*t[rt*2+1][1]*c%mod+c*c%mod*r%mod)%mod;
            t[rt*2][1]=(t[rt*2][1]+c*l%mod)%mod;
            t[rt*2+1][1]=(t[rt*2+1][1]+c*r%mod)%mod;
            lazy[rt*2][2]=(lazy[rt*2][2]+c)%mod;
            lazy[rt*2+1][2]=(lazy[rt*2+1][2]+c)%mod;
            lazy[rt][2]=0;
        }
    }
    void update(int l,int r,int p,int q,LL c,int op,int rt)
    {
        if(p<=l&&r<=q)
        {
            if(op==3)
            {
                t[rt][1]=c*(r-l+1)%mod;
                t[rt][2]=c*c%mod*(r-l+1)%mod;
                t[rt][3]=c*c%mod*c%mod*(r-l+1)%mod;
                lazy[rt][1]=1,lazy[rt][2]=0;lazy[rt][3]=c;
            }
            else if(op==1)
            {
                t[rt][3]=(t[rt][3]+3*t[rt][2]*c%mod+3*t[rt][1]*c%mod*c%mod+c*c%mod*c%mod*(r-l+1)%mod)%mod;
                t[rt][2]=(t[rt][2]+2*t[rt][1]*c%mod+c*c%mod*(r-l+1)%mod)%mod;
                t[rt][1]=(t[rt][1]+c*(r-l+1)%mod)%mod;
                lazy[rt][2]=(lazy[rt][2]+c)%mod;
            }
            else
            {
                t[rt][1]=t[rt][1]*c%mod;
                t[rt][2]=t[rt][2]*c%mod*c%mod;
                t[rt][3]=t[rt][3]*c%mod*c%mod*c%mod;
                lazy[rt][1]=lazy[rt][1]*c%mod;
                lazy[rt][2]=lazy[rt][2]*c%mod;
            }
            return;
        }
        int mid=(l+r)/2;
        pushdown(mid-l+1,r-mid,rt);
        if(p<=mid)update(l,mid,p,q,c,op,rt*2);
        if(q>mid)update(mid+1,r,p,q,c,op,rt*2+1);
        for(int i=1;i<=3;i++)t[rt][i]=(t[rt*2][i]+t[rt*2+1][i])%mod;
    }
    LL query(int l,int r,int p,int q,int op,int rt)
    {
        if(p<=l&&r<=q)return t[rt][op];
        int mid=(l+r)/2;
        pushdown(mid-l+1,r-mid,rt);
        LL res=0;
        if(p<=mid)res=(res+query(l,mid,p,q,op,rt*2))%mod;
        if(q>mid)res=(res+query(mid+1,r,p,q,op,rt*2+1))%mod;
        return res;
    }
    int main()
    {
        int n,m;
        while(~scanf("%d%d",&n,&m))
        {
            if(n==0&&m==0)break;
            build(1,n,1);
            int op,l,r,x;
            while(m--)
            {
                scanf("%d%d%d%d",&op,&l,&r,&x);
                if(op!=4)update(1,n,l,r,x,op,1);
                else printf("%lld
    ",query(1,n,l,r,x,1));
            }
        }
        return 0;
    }
    
  • 相关阅读:
    【杭电】[2035]人见人爱A^B
    【杭电】[2014]青年歌手大奖赛_评委会打分
    【杭电】[2014]青年歌手大奖赛_评委会打分
    【杭电】[2018]母牛的故事
    【杭电】[2018]母牛的故事
    SQL 01: 数据库表的三种关系
    History : The Age of the Samurai(11851868)
    History : Pictures of History 2
    JQuery 07 事件2
    JQuery 07 事件1
  • 原文地址:https://www.cnblogs.com/HooYing/p/12459961.html
Copyright © 2020-2023  润新知