首页 > 代码库 > HDU 4902 Nice boat(线段树)

HDU 4902 Nice boat(线段树)

HDU Nice boat

题目链接

题意:给定一个序列,两种操作,把一段变成x,把一段每个数字,如果他大于x,就变成他和x的gcd,求变换完后,最后的序列。

思路:线段树,每个结点多一个cover表示该位置以下区间是否数字全相同,然后每次延迟操作,最后输出的时候单点查询即可

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 100005;
#define lson(x) ((x<<1)+1)
#define rson(x) ((x<<1)+2)
#define INF 0x3f3f3f3f

int t, n, num[N];
struct Node {
    int l, r, x, setv;
    bool cover;
} node[4 * N];

int gcd(int a, int b) {
    if (!b) return a;
    return gcd(b, a % b);
}

void pushup(int x) {
    node[x].cover = ((node[lson(x)].x == node[rson(x)].x) && node[lson(x)].cover && node[rson(x)].cover);
    node[x].x = node[lson(x)].x;
}

void build(int l, int r, int x = 0) {
    node[x].l = l; node[x].r = r;
    node[x].setv = -1;
    node[x].cover = false;
    if (l == r) {
	node[x].cover = true;
	node[x].x = num[l];
	return;
    }
    int mid = (l + r) / 2;
    build(l, mid, lson(x));
    build(mid + 1, r, rson(x));
    pushup(x);
}

void pushdown(int x) {
    if (node[x].setv != -1) {
	node[lson(x)].setv = node[rson(x)].setv = node[x].setv;
	node[lson(x)].x = node[rson(x)].x = node[x].setv;
	node[x].setv = -1;
    }
}

void add1(int l, int r, int v, int x = 0) {
    if (node[x].l >= l && node[x].r <= r) {
	node[x].setv = v;
	node[x].x = v;
	return;
    }
    int mid = (node[x].l + node[x].r) / 2;
    pushdown(x);
    if (l <= mid) add1(l, r, v, lson(x));
    if (r > mid) add1(l, r, v, rson(x));
    pushup(x);
}

void add2(int l, int r, int v, int x = 0) {
    if (node[x].cover && node[x].x <= v) return;
    if (node[x].l >= l && node[x].r <= r && node[x].cover) {
	node[x].x = gcd(node[x].x, v);
	node[x].setv = node[x].x;
	return;
    }
    pushdown(x);
    int mid = (node[x].l + node[x].r) / 2;
    if (l <= mid) add2(l, r, v, lson(x));
    if (r > mid) add2(l, r, v, rson(x));
    pushup(x);
}

int query(int k, int x = 0) {
    if (node[x].l == node[x].r)
	return node[x].x;
    int mid = (node[x].l + node[x].r) / 2;
    pushdown(x);
    if (k <= mid) return query(k, lson(x));
    if (k > mid) return query(k, rson(x));
}

int main() {
    scanf("%d", &t);
    while (t--) {
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
	    scanf("%d", &num[i]);
	build(1, n);
	int q;
	scanf("%d", &q);
	int c, a, b, v;
	while (q--) {
	    scanf("%d%d%d%d", &c, &a, &b, &v);
	    if (c == 1)
		add1(a, b, v);
	    else if (c == 2)
		add2(a, b, v);
	}
	for (int i = 1; i <= n; i++)
	    printf("%d ", query(i));
	printf("\n");
    }
    return 0;
}