HYSBZ - 5312 冒险

题意:

给定一个长度为 n n n 的数组 a a a,有 q q q 次操作,① 1 , l , r , x 1, l, r, x 1,l,r,x,区间 &   x \&~x & x;② 2 , l , r , x 2, l, r, x 2,l,r,x,区间 ∣   x \mid~x  x;③ 3 , l , r 3, l, r 3,l,r,查询区间最大值。 ( n , q ≤ 2 × 1 0 5 , 0 ≤ a i ≤ 2 20 ) (n, q \leq 2×10^5, 0 \leq a_i \leq 2^{20}) (n,q2×105,0ai220)

链接:

https://vjudge.net/problem/HDU-5828

解题思路:

位运算考虑拆位用线段树维护,但需要维护的是最值,不像区间和可以分开维护。区间 &   x \&~x & x,最值可以直接维护当且仅当区间所有数相同,更进一步考虑,将每个位分开更新,某个位可以直接更新当且仅当区间所有数该位相同。那么分每个位考虑操作, &   x \&~x & x,当 x i = 0 x_i = 0 xi=0 有效,区间赋值 0 0 0 ∣   x \mid~x  x,当 x i = 1 x_i = 1 xi=1 有效,区间赋值 1 1 1,区间直接更新当且仅当区间所有数该位相同,定义结点势能为 0 0 0 当且仅当满足该位相同,否则为 1 1 1。注意以下讨论仍只考虑单个二进制位,其他各位同理。初始总势能为 O ( n l o g n ) O(nlogn) O(nlogn),更新时先定位 O ( l o g n ) O(logn) O(logn) 个区间,若区间该位不全相同,即势能非 0 0 0,那么暴力向下访问,回溯时势能清 0 0 0,暴力访问的结点数与势能同阶。

综上,对每位单独考虑更新即可,但不必也不能分开用多棵线段树维护。总复杂度 O ( n l o g n l o g a + m l o g n ) O(nlognloga + mlogn) O(nlognloga+mlogn)

参考代码:
#include<bits/stdc++.h>
 
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define sz(a) ((int)a.size())
#define pb push_back
#define lson (rt << 1)
#define rson (rt << 1 | 1)
#define gmid (l + r >> 1)
const int maxn = 2e5 + 5;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;

const int msk = (1 << 21) - 1;
int a[maxn];
int n, m;

struct SegTree{

    int mx[maxn << 2], equ[maxn << 2], tad[maxn << 2], tor[maxn << 2];
    void pushUp(int rt){

        mx[rt] = max(mx[lson], mx[rson]);
        equ[rt] = equ[lson] & equ[rson] & (mx[lson] ^ mx[rson] ^ msk);
    }
    void build(int l, int r, int rt){

        tad[rt] = msk, tor[rt] = 0;
        if(l == r){

            mx[rt] = a[l], equ[rt] = msk;
            return;
        }
        int mid = gmid;
        build(l, mid, lson);
        build(mid + 1, r, rson);
        pushUp(rt);
    }
    void pushDown2(int rt, int son){

        tad[son] &= tad[rt];
        tor[son] &= tad[rt];
        mx[son] &= tad[rt];

        tor[son] |= tor[rt];
        mx[son] |= tor[rt];
    }
    void pushDown(int rt){

        pushDown2(rt, lson);
        pushDown2(rt, rson);
        tad[rt] = msk, tor[rt] = 0;
    }
    void updateAnd(int l, int r, int rt, int L, int R, int val){

        if(l >= L && r <= R){

            tad[0] = (val ^ msk) & equ[rt] ^ msk, tor[0] = 0;
            pushDown2(0, rt);
            val ^= tad[0] ^ msk;
            if(val == msk) return;
        }
        int mid = gmid;
        pushDown(rt);
        if(L <= mid) updateAnd(l, mid, lson, L, R, val);
        if(R > mid) updateAnd(mid + 1, r, rson, L, R, val);
        pushUp(rt);
    }
    void updateOr(int l, int r, int rt, int L, int R, int val){

        if(l >= L && r <= R){

            tad[0] = msk, tor[0] = val & equ[rt];
            pushDown2(0, rt);
            val ^= tor[0];
            if(!val) return;
        }
        int mid = gmid;
        pushDown(rt);
        if(L <= mid) updateOr(l, mid, lson, L, R, val);
        if(R > mid) updateOr(mid + 1, r, rson, L, R, val);
        pushUp(rt);
    }
    int query(int l, int r, int rt, int L, int R){

        if(l >= L && r <= R) return mx[rt];
        int mid = gmid, ret = 0;
        pushDown(rt);
        if(L <= mid) ret = max(ret, query(l, mid, lson, L, R));
        if(R > mid) ret = max(ret, query(mid + 1, r, rson, L, R));
        return ret;
    }
} tr;

int main(){

    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> m;
    for(int i = 1; i <= n; ++i){

        cin >> a[i];
    }
    tr.build(1, n, 1);
    while(m--){

        int opt, x, y, z; cin >> opt >> x >> y;
        if(opt == 1){

            cin >> z;
            tr.updateAnd(1, n, 1, x, y, z);
        }
        else if(opt == 2){

            cin >> z;
            tr.updateOr(1, n, 1, x, y, z);
        }
        else{

            int ret = tr.query(1, n, 1, x, y);
            cout << ret << "\n";
        }
    }
    return 0;;
}
Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值