hdu 4578 Transformation(线段树)

线段树上的多操作。。。


题目大意:

树上 的初始值为0,然后有下列三种操作和求和。

1  x y c  在X-Y的之间全部加上C。

2  x y c  在X-Y的之间全部乘上C。

3  x y c  在X-Y之间的全部变成C。

4  x y c  输出在X-Y之间的所有数的C方的和。。。


思路:

因为存在两种不兼容的操作(如果直接放一起的话会出现顺序不同的影响,(3+2)*4   和 3*4+2  显然是不一样的)

所以每次合并操作的时候  就要把子树的操作推下去清除掉。

当然  如果这个区间的所有值都是一样的话。那么可以直接进行操作。

然后就是Query了。

因为要求出很多的平方 或者 立方和。

那么我们就去找所有区间的值是一样的区间。拿出来现乘方  再算有多少个。


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#define lson num<<1,s,mid
#define rson num<<1|1,mid+1,e
#define maxn 100005
const int mod = 10007;
using namespace std;

int add[maxn<<2];
int mul[maxn<<2];
int cov[maxn<<2];
int tre[maxn<<2];
int n,m;

void pushdown(int num)
{
    if(cov[num])//如果这个区间是值一样的 
    {
        tre[num<<1]=tre[num<<1|1]=tre[num];
        cov[num<<1]=cov[num<<1|1]=1;
        add[num<<1]=add[num<<1|1]=0;
        mul[num<<1]=mul[num<<1|1]=1;
        cov[num]=0;
        return;
    }
    if(add[num]!=0)//不一样的话  要把ADD推下去
    {
        if(cov[num<<1])
        {
            tre[num<<1]+=add[num];
            tre[num<<1]%=mod;
        }
        else
        {
            pushdown(num<<1);
            add[num<<1]+=add[num];
            add[num<<1]%=mod;
        }

        if(cov[num<<1|1])
        {
            tre[num<<1|1]+=add[num];
            tre[num<<1|1]%=mod;
        }
        else
        {
            pushdown(num<<1|1);
            add[num<<1|1]+=add[num];
            add[num<<1|1]%=mod;
        }

        add[num]=0;
    }
    if(mul[num]!=1)
    {
        if(cov[num<<1])
        {
            tre[num<<1]*=mul[num];
            tre[num<<1]%=mod;
        }
        else
        {
            mul[num<<1]*=mul[num];
            mul[num<<1]%=mod;
        }

        if(cov[num<<1|1])
        {
            tre[num<<1|1]*=mul[num];
            tre[num<<1|1]%=mod;
        }
        else
        {
            mul[num<<1|1]*=mul[num];
            mul[num<<1|1]%=mod;
        }
        mul[num]=1;
    }
}


void build(int num,int s,int e)
{
    add[num]=0;
    mul[num]=1;
    cov[num]=0;
    tre[num]=0;
    if(s==e)
    {
        cov[num]=1;
        return;
    }
    int mid=(s+e)>>1;
    build(lson);
    build(rson);
}

void update(int num,int s,int e,int l,int r,int val,int op)
{
    if(l<=s && r>=e)
    {
        if(op==3)
        {
            add[num]=0;
            mul[num]=1;
            cov[num]=1;
            tre[num]=val;
        }
        else
        {
            if(cov[num])
            {
                if(op==1)
                {
                    tre[num]+=val;
                    tre[num]%=mod;
                }
                else
                {
                    tre[num]*=val;
                    tre[num]%=mod;
                }
            }
            else
            {
                pushdown(num);

                if(op==1)
                {
                    add[num]+=val;
                    add[num]%=mod;
                }
                else
                {
                    mul[num]*=val;
                    mul[num]%=mod;
                }
            }
        }
        return;
    }

    pushdown(num);

    int mid=(s+e)>>1;

    if(l<=mid)update(lson,l,r,val,op);
    if(r>mid)update(rson,l,r,val,op);
}

int Q_Q(int num,int s,int e,int c)
{
    printf("```%d
",num);
    int mid=(s+e)>>1;
    if(cov[num]==1)
    {
        int tmp=1;
        for(int aa=0;aa<c;aa++)
        {
            tmp*=tre[num];
            tmp%=mod;
        }
        tmp*=(e-s+1);
        tmp%=mod;
        return tmp;
    }
    pushdown(num);
    Q_Q(lson,c);
    Q_Q(rson,c);
}
int query(int num,int s,int e,int l,int r,int c)
{
    int mid=(s+e)>>1;
    if(l==s && r==e)
    {
        if(cov[num])
        {
            int tmp=1;
            while(c--)
            {
                tmp*=tre[num];
                tmp%=mod;
            }
            tmp*=(e-s+1);
            tmp%=mod;
            return tmp;
        }
    }
    pushdown(num);

    if(r<=mid)return query(lson,l,r,c);
    else if(l>mid)return query(rson,l,r,c);
    else return (query(lson,l,mid,c) + query(rson,mid+1,r,c))%mod;
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        if(n==0 && m==0)break;
        int op,lef,rig,c;
        build(1,1,n);
        while(m--)
        {
            scanf("%d%d%d%d",&op,&lef,&rig,&c);

            if(op!=4)update(1,1,n,lef,rig,c,op);
            else printf("%d
",query(1,1,n,lef,rig,c)%mod);
        }
    }
    return 0;
}



原文地址:https://www.cnblogs.com/riskyer/p/3366022.html