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;;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值