hdu4902 线段树区间更新

时限15s,根本就是怎么水怎么过啊。

维护两个标记,一个赋值一个取gcd,保证一个节点只有一种标记,多余的向下pushdown,由于只要最后结果,不用pushup,直接水水注意细节就行了。

PE了一次,格式控制挺反人类的。

附代码:

#include 
#include 
#include 

using namespace std;

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define delf int m=(l+r)>>1
const int MAX=100010;
int s[MAX<<2];
int g[MAX<<2];
int n,q;

void swap(int &a,int &b)
{
    if (ag[rt])
                    g[rt<<1]=gcd(g[rt<<1],g[rt]);
            }
        }
        else if (s[rt<<1]!=-1)
        {
            if (s[rt<<1]>g[rt])
            {
                s[rt<<1]=gcd(s[rt<<1],g[rt]);
            }
        }
        else
            g[rt<<1]=g[rt];
        if (g[rt<<1|1]!=-1)
        {
            if (m+1!=r)
            {
                pushdown(rson);
                g[rt<<1|1]=g[rt];
            }
            else
            {
                if (g[rt<<1|1]>g[rt])
                    g[rt<<1|1]=gcd(g[rt<<1],g[rt]);
            }
        }
        else if (s[rt<<1|1]!=-1)
        {
            if (s[rt<<1|1]>g[rt])
            {
                s[rt<<1|1]=gcd(s[rt<<1|1],g[rt]);
            }
        }
        else
            g[rt<<1|1]=g[rt];
        g[rt]=-1;
    }
    return ;
}

void build(int l,int r,int rt)
{
    s[rt]=g[rt]=-1;
    if (l==r)
    {
        scanf("%d",&s[rt]);
        return ;
    }
    delf;
    build(lson);
    build(rson);
    return ;
}

void update1(int L,int R,int x,int l,int r,int rt)      //赋值操作
{
    if (L<=l&&r<=R)
    {
        s[rt]=x;
        g[rt]=-1;
        return ;
    }
    pushdown(l,r,rt);
    delf;
    if (L<=m)
        update1(L,R,x,lson);
    if (R>m)
        update1(L,R,x,rson);
    return ;
}

void update2(int L,int R,int x,int l,int r,int rt)      //gcd操作
{
    if (L<=l&&r<=R)
    {
        if (s[rt]!=-1)      //如果存在赋值操作,将新的gcd替代赋值操作变成新的赋值操作
        {
            if (s[rt]>x)
            {
                s[rt]=gcd(x,s[rt]);
            }
        }
        else if (g[rt]!=-1)     //如果存在gcd操作,将gcd操作向下更新,记录新的gcd操作
        {
            pushdown(l,r,rt);
            g[rt]=x;
        }
        else
            g[rt]=x;    //否则,记录新的gcd操作
        return ;
    }
    pushdown(l,r,rt);
    delf;
    if (L<=m)
        update2(L,R,x,lson);
    if (R>m)
        update2(L,R,x,rson);
    return ;
}

void query(int l,int r,int rt)
{
    if (l==r)
    {
        if (s[rt]!=-1)
            printf("%d",s[rt]);
        else
            printf("%d",g[rt]);
        printf(" ");
        return ;
    }
    delf;
    pushdown(l,r,rt);
    query(lson);
    query(rson);
    return ;
}

int main()
{
    int T;
    scanf("%d",&T);
    while (T--)
    {
        scanf("%d",&n);
        build(1,n,1);
        scanf("%d",&q);
        while (q--)
        {
            int t,l,r,x;
            scanf("%d%d%d%d",&t,&l,&r,&x);
            if (t==1)
                update1(l,r,x,1,n,1);
            if (t==2)
                update2(l,r,x,1,n,1);
        }
        query(1,n,1);
        printf("\n");
    }
}


你可能感兴趣的:(线段树)