zoukankan      html  css  js  c++  java
  • HDU4578 Transformation(线段树)

    /**
        有3种改变操作,需要3个lazy来记录;
        每种操作之间有优先关系
        change>mul>add;
        传递时按优先关系进行
        记录p= 1 2 3使得sum即可
        注意取模
    */
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #include<map>
    #include<set>
    
    
    #define lson l,mid,now<<1
    #define rson mid+1,r,now<<1|1
    #define ls now<<1
    #define rs now<<1|1
    #define all left,right,k
    
    #define inf 0x3f3f3f3f
    #define ll long long
    #define mem(a,b) memset(a,b,sizeof(a))
    
    
    const int maxn=1e5+10;
    const int mod=10007;
    
    using namespace std;
    
    ll tree[4*maxn][4],add[4*maxn],mul[4*maxn],ch[4*maxn];
    ///   数            lazy加      lazy乘       lazy替换
    
    void built(int l,int r,int now)
    {
        int mid=(l+r)>>1;
        add[now]=ch[now]=0;
        mul[now]=1;
        tree[now][1]=tree[now][2]=tree[now][3]=0;
        if(l==r) return ;
        built(lson);
        built(rson);
    }
    
    void pushup(int now)
    {
        for(int i=1;i<=3;i++)
            tree[now][i]=(tree[ls][i]+tree[rs][i])%mod;
    }
    
    void pushdown(int l,int r,int now)
    {
        int mid=(l+r)>>1;
        if(ch[now]!=0)///如果发生替换
        {
            ///改变ls rs的值 直接计算即可
            tree[ls][1]=(ch[now]*(mid-l+1))%mod;
            tree[ls][2]=((ch[now]*ch[now])%mod*(mid-l+1))%mod;
            tree[ls][3]=(((ch[now]*ch[now])%mod*ch[now])%mod)*(mid-l+1);
    
            tree[rs][1]=(ch[now]*(r-mid))%mod;
            tree[rs][2]=((ch[now]*ch[now])%mod*(r-mid))%mod;
            tree[rs][3]=(((ch[now]*ch[now])%mod*ch[now])%mod)*(r-mid);
    
            ///将ch传递 ls rs之前未传递的+*清零
            ch[ls]=ch[rs]=ch[now];
            add[ls]=add[rs]=ch[now]=0;
    		mul[ls]=mul[rs]=1;
        }
    
        if(mul[now]!=1)///乘法
        {
            ///mul 传递乘法分配
            add[ls]=(add[ls]*mul[now])%mod;
            add[rs]=(add[rs]*mul[now])%mod;
            mul[ls]=(mul[ls]*mul[now])%mod;
            mul[rs]=(mul[rs]*mul[now])%mod;
    
            tree[ls][1]=(tree[ls][1]*mul[now])%mod;
            tree[ls][2]=((tree[ls][2]*mul[now])%mod*mul[now])%mod;
            tree[ls][3]=(((tree[ls][3]*mul[now])%mod*mul[now])%mod*mul[now])%mod;
    
    		tree[rs][1]=(tree[rs][1]*mul[now])%mod;
            tree[rs][2]=((tree[rs][2]*mul[now])%mod*mul[now])%mod;
            tree[rs][3]=(((tree[rs][3]*mul[now])%mod*mul[now])%mod*mul[now])%mod;
    
            mul[now]=1;
        }
    
        if(add[now]!=0)///加法
        {
            add[ls]=(add[ls]+add[now])%mod;
            add[rs]=(add[rs]+add[now])%mod;
            ///(a+b)^2=a^2+2ab+b^2;
            ///累加一下 得到(a1+b)^2+...+(an+b)^2=(a1^2+..+an^2)+2*(a1+..+an)*b+(1+...+n)b^2;
            ///同理可以得到(a+b)^3;
            
            
            tree[ls][3]=(tree[ls][3]+(tree[ls][2]*add[now]*3)%mod+((add[now]*add[now])%mod*tree[ls][1]*3)%mod+((add[now]*add[now])%mod*add[now])%mod*(mid-l+1))%mod;
            tree[ls][2]=(tree[ls][2]+(tree[ls][1]*add[now]*2)%mod+(add[now]*add[now])%mod*(mid-l+1))%mod;
            tree[ls][1]=(tree[ls][1]+add[now]*(mid-l+1)%mod)%mod;
    
            tree[rs][3]=(tree[rs][3]+(tree[rs][2]*add[now]*3)%mod+((add[now]*add[now])%mod*tree[rs][1]*3)%mod+((add[now]*add[now])%mod*add[now]%mod)*(r-mid))%mod;
            tree[rs][2]=(tree[rs][2]+(tree[rs][1]*add[now]*2)%mod+(add[now]*add[now])%mod*(r-mid))%mod;
            tree[rs][1]=(tree[rs][1]+add[now]*(r-mid)%mod)%mod;
    
            add[now]=0;
        }
    }
    
    void updata(int l,int r,int now,int left,int right,int k,int cmd)
    {
        int mid=(l+r)>>1,len=r-l+1;
        if(left<=l&&r<=right)
        {
            if(cmd==1)
            {
                add[now]=(add[now]+k)%mod;
                tree[now][3]=(tree[now][3]+((tree[now][2]*k)%mod*3)%mod+(((tree[now][1]*k)%mod*k)%mod*3)%mod+(((len*k)%mod*k)%mod*k)%mod)%mod;
                ///裂项展开相加
                tree[now][2]=(tree[now][2]+((tree[now][1]*k)%mod*2)%mod+((len*k)%mod*k)%mod)%mod;
    
                tree[now][1]=(tree[now][1]+(k*len)%mod)%mod;
            }
            if(cmd==2)
            {
                add[now]=(add[now]*k)%mod;
                mul[now]=(mul[now]*k)%mod;
    
                tree[now][1]=(tree[now][1]*k)%mod;
                tree[now][2]=((tree[now][2]*k)%mod*k)%mod;
                tree[now][3]=(((tree[now][3]*k)%mod*k)%mod*k)%mod;
            }
            if(cmd==3)
            {
                ///如果是替换操作 将当前值改变
                ///还要将之前为传递的+*操作标记清掉
                ch[now]=k%mod;
                add[now]=0;
                mul[now]=1;
    
                tree[now][1]=(k*len)%mod;
                tree[now][2]=((k*k)%mod*len)%mod;
                tree[now][3]=(((k*k)%mod*k)%mod*len)%mod;
            }
            return ;
        }
        if(add[now]!=0||mul[now]!=1||ch[now]!=0)
            pushdown(l,r,now);
        if(left<=mid) updata(lson,all,cmd);
        if(right>mid) updata(rson,all,cmd);
        pushup(now);
    }
    
    int query(int l,int r,int now,int left,int right,int k)
    {
        int mid=(l+r)>>1;
        if(left<=l&&r<=right)
        {
            return tree[now][k];
        }
        if(add[now]!=0||mul[now]!=1||ch[now]!=0)
            pushdown(l,r,now);
        int ans=0;
        if(left<=mid) ans+=query(lson,all);
        if(right>mid) ans+=query(rson,all);
        return ans%mod;
    }
    
    int main(){
        int n,m;
        while(scanf("%d%d",&n,&m))
        {
            if(n+m==0) break;
            int cmd,l,r,k;
            built(1,n,1);
            while(m--)
            {
                scanf("%d%d%d%d",&cmd,&l,&r,&k);
                if(cmd==4)
                    printf("%d
    ",query(1,n,1,l,r,k));
                else
                    updata(1,n,1,l,r,k,cmd);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    采用重写tostring方法使ComboBox显示对象属性
    JavaScript中正则表达式test()、exec()、match() 方法
    高级软件工程实践总结作业
    用户使用调查报告
    Beta阶段置顶集合
    Beta冲刺阶段总结随笔
    Beta冲刺Day7
    Beta冲刺Day6
    Beta冲刺Day5
    Beta冲刺Day4
  • 原文地址:https://www.cnblogs.com/minun/p/10473769.html
Copyright © 2011-2022 走看看