zoukankan      html  css  js  c++  java
  • 七夕——ORMAX(线段树)

    ORMAX

    题目链接:https://ac.nowcoder.com/acm/contest/18962/G

    题目描述:

    给定一个数组A,长度为n,你需要对该数组进行两种操作:

    查询操作:1 l r 存在子区间[X,Y] 使得AX or AX+1 or AX+2  ... AY-2 or AY-1 or AY的值最大,输出这个最大值。

    修改操作:2 l r x 将区间[l,r]的数全修改为x。

    这里or指或操作。

    见过最漂亮的线段树模板了,递归建树、递归维护

    这题确实可以用线段树做,因为一个数A或运算他自己的结果还是A(即A|A=A)所以区间修改操作时可以直接把所在的区间改成X,代码代码如下:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1000001;
    int n, m, a[maxn], L[maxn << 2], R[maxn << 2], sum[maxn << 2], tag[maxn << 2], ans;
    void bulid(int x, int l, int r)
    {
        L[x] = l, R[x] = r;
        if(l == r)
        {
            sum[x] = a[l];
            return;
        }
        int mid = l + r >> 1;
        bulid(x << 1, l, mid);
        bulid(x << 1 | 1, mid + 1, r);
        sum[x] = sum[x << 1] | sum[x << 1 | 1];
    }
    void pushdown(int x, int data)
    {
        tag[x] = data;
        sum[x] = data;
    }
    void updata(int x, int l, int r, int data)
    {
        if(r < L[x] || l > R[x])
        {
            return;
        }
        if(l <= L[x] && r >= R[x])
        {
            sum[x] = data;
            tag[x] = data;
            return;
        }
        if(tag[x])
        {
            pushdown(x << 1, tag[x]);
            pushdown(x << 1 | 1, tag[x]);
            tag[x] = 0;
        }
        updata(x << 1, l, r, data);
        updata(x << 1 | 1, l, r, data);
        sum[x] = sum[x << 1] | sum[x << 1 | 1];
    }
    void getsum(int x, int l, int r)
    {
        if(r < L[x] || l > R[x])
        {
            return;
        }
        if(l <= L[x] && r >= R[x])
        {
            ans |= sum[x];
            return;
        }
        if(tag[x])
        {
            pushdown(x << 1, tag[x]);
            pushdown(x << 1 | 1, tag[x]);
            tag[x] = 0;
        }
        getsum(x << 1, l, r);
        getsum(x << 1 | 1, l, r);
    }
    int main()
    {
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; i++)
        {
            scanf("%d", &a[i]);
        }
        bulid(1, 1, n);
        for(int i = 1; i <= m; i++)
        {
            int op;
            scanf("%d", &op);
            if(op == 1)
            {
                int l, r;
                scanf("%d%d", &l, &r);
                ans = 0;
                getsum(1, l, r);
                printf("%d
    ", ans);
            }
            else
            {
                int l, r, k;
                scanf("%d%d%d", &l, &r, &k);
                updata(1, l, r, k);
            }
        }
        return 0;
    }

      放着欣赏。

  • 相关阅读:
    【leetcode】Remove Duplicates from Sorted Array I & II(middle)
    Android--Activity在跳转时携带数据
    HDU 5371 Manacher
    Java之旅hibernate(2)——文件夹结构
    【智能路由器】让MT7620固件openwrt支持USB
    Android Context 是什么?
    分治法解决高速排序问题
    Alluxio增强Spark和MapReduce存储能力
    UVA
    《React-Native系列》44、基于多个TextInput的键盘遮挡处理方案优化
  • 原文地址:https://www.cnblogs.com/thx2199/p/15145757.html
Copyright © 2011-2022 走看看