HDU 4902 Nice boat(线段树 区间更新)


题意:

给你一个区间,每次可以进行两种操作

1:把区间中的数全都变成x 

2:把区间中大于x的数变成gcd(a[i], x)


最后输出序列。(n,m<=10^6)

时限 15s,暴力也能过。。。。



线段树做法,区间更新,lazy标记,到需要更新的时候才更新。

num[rt] != -1,表示 区间 L[rt]~R[rt] 所有的数都相同。



#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

const int maxn = 100000 + 10;
int num[maxn*4], lazy[maxn*4], L[maxn*4], R[maxn*4];

int gcd(int a, int b){ return b?gcd(b, a%b):a; }

void PushUp(int rt){
    if(num[rt<<1]==num[rt<<1|1]){
        num[rt] = num[rt<<1];
    }else num[rt] = -1;
}

void PushDown(int rt)
{
    if(lazy[rt]){
        lazy[rt<<1] = lazy[rt<<1|1] = 1;
        num[rt<<1] = num[rt<<1|1] = num[rt];
        lazy[rt] = 0;
    }
}

void build(int rt, int l, int r)
{
    L[rt] = l, R[rt] = r;
    lazy[rt] = 0;
    if(l == r)
    {
        scanf("%d", &num[rt]);
        return ;
    }
    int mid = (l+r)>>1;
    build(rt<<1, l, mid);
    build(rt<<1|1, mid+1, r);
}

void update1(int rt, int l, int r, int x){
    if(l<=L[rt] && R[rt]<=r){
        lazy[rt] = 1;
        num[rt] = x;
        return ;
    }
    PushDown(rt);
    int mid = (L[rt]+R[rt])>>1;
    if(l<=mid) update1(rt<<1, l, r, x);
    if(r> mid) update1(rt<<1|1, l, r, x);
    PushUp(rt);
}

void update2(int rt, int l, int r, int x)
{
    if(l<=L[rt] && R[rt]<=r && num[rt]!=-1) {
        if(num[rt]>x){
            num[rt] = gcd(num[rt], x);
            lazy[rt] = 1;
        }
        return ;
    }
    PushDown(rt);
    int mid = (L[rt]+R[rt])>>1;
    if(l<=mid) update2(rt<<1, l, r, x);
    if(r> mid) update2(rt<<1|1, l, r, x);
    PushUp(rt);
}
void query(int rt)
{
    if(L[rt]==R[rt]){
        printf("%d ", num[rt]);
        return ;
    }
    PushDown(rt);
    int mid = (L[rt]+R[rt])>>1;
    query(rt<<1);
    query(rt<<1|1);
}

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


你可能感兴趣的:(HDU 4902 Nice boat(线段树 区间更新))