zoukankan      html  css  js  c++  java
  • HDU 4578 Transformation 线段树

    三个标记,注意到乘法标记会影响加法标记,然后就是一般的成段更新了。

    AC后搜别人的题解发现原来替换标记可以用一个乘0和加c代替,这样就不用三个标记了。

    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<iostream>
    #include<sstream>
    #include<cmath>
    #include<climits>
    #include<string>
    #include<map>
    #include<queue>
    #include<vector>
    #include<stack>
    #include<set>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pii;
    #define pb(a) push_back(a)
    #define INF 0x1f1f1f1f
    #define lson idx<<1,l,mid
    #define rson idx<<1|1,mid+1,r
    #define PI  3.1415926535898
    template<class T> T min(const T& a,const T& b,const T& c) {
        return min(min(a,b),min(a,c));
    }
    template<class T> T max(const T& a,const T& b,const T& c) {
        return max(max(a,b),max(a,c));
    }
    void debug() {
    #ifdef ONLINE_JUDGE
    #else
    
        freopen("d:\in.txt","r",stdin);
       // freopen("d:\out1.txt","w",stdout);
    #endif
    }
    int getch() {
        int ch;
        while((ch=getchar())!=EOF) {
            if(ch!=' '&&ch!='
    ')return ch;
        }
        return EOF;
    }
    
    const int maxn=100100;
    const int mod=10007;
    struct Tree
    {
        int sum[maxn<<2][3];
        int mul[maxn<<2],add[maxn<<2],setv[maxn<<2];
        void setv_(int idx,int len,int v)
        {
            int x=v;
            for(int i=0;i<3;i++)
            {
                sum[idx][i]=x*len%mod;
                x=x*v%mod;
            }
            setv[idx]=v;
            mul[idx]=1;
            add[idx]=0;
        }
    
        void add_(int idx,int len,int v)
        {
            sum[idx][2]=(sum[idx][2]+3*sum[idx][1]*v%mod+3*sum[idx][0]*v%mod*v%mod+v%mod*v%mod*v%mod*len%mod)%mod;
            sum[idx][1]=(sum[idx][1]+2*sum[idx][0]*v%mod+v*v%mod*len%mod)%mod;
            sum[idx][0]=(sum[idx][0]+v*len%mod)%mod;
            add[idx]=(add[idx]+v)%mod;
        }
    
        void mul_(int idx,int len,int v)
        {
            sum[idx][2]=sum[idx][2]*v%mod*v%mod*v%mod;
            sum[idx][1]=sum[idx][1]*v%mod*v%mod;
            sum[idx][0]=sum[idx][0]*v%mod;
            mul[idx]=mul[idx]*v%mod;
            add[idx]=add[idx]*v%mod;
        }
        void PushUp(int idx)
        {
            for(int i=0;i<3;i++)
                sum[idx][i]=(sum[idx<<1][i]+sum[idx<<1|1][i])%mod;
        }
        void PushDown(int idx,int l,int r)
        {
            int mid=(r+l)>>1;
            if(setv[idx]!=-1)
            {
                setv_(idx<<1,mid-l+1,setv[idx]);
                setv_(idx<<1|1,r-mid,setv[idx]);
                setv[idx]=-1;
            }
            if(mul[idx]!=1)
            {
                mul_(idx<<1,mid-l+1,mul[idx]);
                mul_(idx<<1|1,r-mid,mul[idx]);
                mul[idx]=1;
            }
            if(add[idx]!=0)
            {
                add_(idx<<1,mid-l+1,add[idx]);
                add_(idx<<1|1,r-mid,add[idx]);
                add[idx]=0;
            }
        }
        void build(int idx,int l,int r)
        {
            setv[idx]=-1;
            mul[idx]=1;
            add[idx]=0;
            sum[idx][0]=sum[idx][1]=sum[idx][2]=0;
            if(l==r)return ;
            int mid=(r+l)>>1;
            build(lson);
            build(rson);
        }
        int update(int idx,int l,int r,int tl,int tr,int op,int v)
        {
            if(tl<=l&&tr>=r)
            {
                if(op==1)
                    add_(idx,r-l+1,v);
                else if(op==2)
                    mul_(idx,r-l+1,v);
                else setv_(idx,r-l+1,v);
                return 0;
            }
            PushDown(idx,l,r);
            int mid=(r+l)>>1;
            if(tl<=mid)update(lson,tl,tr,op,v);
            if(tr>mid)update(rson,tl,tr,op,v);
            PushUp(idx);
            return 0;
        }
        int query(int idx,int l,int r,int tl,int tr,int p)
        {
            if(tl<=l&&tr>=r)
                return sum[idx][p-1];
            PushDown(idx,l,r);
            int mid=(r+l)>>1;
            int x=0;
            if(tl<=mid)x=(x+query(lson,tl,tr,p))%mod;
            if(tr>mid)x=(x+query(rson,tl,tr,p))%mod;
            return x;
        }
    };
    
    Tree tree;
    int main()
    {
        debug();
        int n,m;
        while(scanf("%d%d",&n,&m)!=EOF&&(n||m))
        {
            tree.build(1,1,n);
            for(int i=1;i<=m;i++)
            {
                int op,a,b,v;
                scanf("%d%d%d%d",&op,&a,&b,&v);
                if(op==4)
                    printf("%d
    ",tree.query(1,1,n,a,b,v));
                else tree.update(1,1,n,a,b,op,v);
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Linux进程理解与实践(四)wait函数处理僵尸进程
    Linux进程理解与实践(三)进程终止函数和exec函数族的使用
    system V信号量和Posix信号量
    Linux进程间通信方式--信号,管道,消息队列,信号量,共享内存
    linux 高并发socket通信模型
    信号集函数
    进程间通信使用信号
    使用消息队列
    改变域名,php
    php函数
  • 原文地址:https://www.cnblogs.com/BMan/p/3309962.html
Copyright © 2011-2022 走看看