• 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("
    ");
        }
        return 0;
    }


  • 相关阅读:
    Matlab中transpose函数的使用
    Matlab中cell2mat的使用
    Matlab中find函数的使用
    Matlab中数组下标是logical,如何处理?
    Matlab中mat2cell的使用
    判断一棵树是否是另一棵树的子树
    链表中倒数第k个结点
    古德-图灵估计
    好书记录
    编程思路总结——递归
  • 原文地址:https://www.cnblogs.com/gavanwanggw/p/7239869.html
Copyright © 2020-2023  润新知