CF1936D. Bitwise Paradox-位运算、分治、线段树

news/2024/11/15 20:10:39/文章来源:https://www.cnblogs.com/yoshinow2001/p/18297832

link:https://codeforces.com/contest/1936/problem/D
题意:给两个长度为 \(n\) 的序列 \(a\)\(b\),对一个区间 \([l,r]\),称 \([l,r]\)的,若:\((b_l|\dots|b_r)\geq v\)。一个区间的 美丽值 定义为区间内 \(a\) 的最大值。现在有 \(q\) 个操作:

  • 1、\(b_i\to x\).
  • 2、给 \(l,r\),问 \([l,r]\) 的所有的子区间 \([l_0,r_0]\) ,美丽值最小的是多少?

分析性质:

  • 1、如果某个区间 \([l,r]\) 是好的,则更大的区间 \([L,R]\)\([l,r]\subset [L,R]\)) 一定是好的,同时因为美丽值是max,因此一定会更大,而我们希望的是最小的美丽值,因此真正关心的是一个个极小的好区间
  • 2、对于 \(\geq v\) 的位运算问题,可以改写成 \(>v-1\),然后拆位考虑,具体见3
  • 3、对于区间的子区间问题,会想到最大子段和问题(同样是问区间的子区间):\([l,r]\) 的答案,要么来自于左半边,要么来自右半边,要么来自某个跨过中点的区间。前两个递归解决,考察最后一个情况:
    • 假设从中点向着两边扩展,我希望找到一些 或和\(>v-1\) 的区间,如果只看一个方向,首先要注意到一个性质(我场内就没注意到…)——按位或是单调不减的,而每次变大一定是某个二进制的 \(0\to 1\),因此会让按位或变大的位置,只有\(O(\log V)\) 个。

    • 从左到右和从右到左是类似的,因此我们考虑用线段树维护两个长度为31的数组 pre,suf,表示区间从两个方向扩展,二进制的某一位为 \(1\) 的第一个位置,这个信息很好合并。

    • 答案怎么更新?就是看拆位,我们想的时候举个栗子,比如要严格大于二进制数:01011,那么我可以是1xxxx011xx,这样。也就是说我从高到低去看:一方面是b[]的这位能不能凑出1,另一方面是 \(v-1\) 的这一位是多少。

      • 如果只能凑出0就没什么好说了,如果能凑出1,那我希望\(\max a\) 尽量小,就要去比较左右两边用哪边的 1 更好,所以需要维护一个当前扩展出去的区间,以及涉及到一个静态RMQ,用st表处理。
        核心代码:
sgt operator +(const sgt &ls,const sgt &rs){sgt ret;int L=ls.r;ret.l=ls.l;int R=rs.l;ret.r=rs.r;ret.v=min(ls.v,rs.v);for(int i=30;i>=0;i--){ret.pre[i]=(ls.pre[i]?ls.pre[i]:rs.pre[i]);ret.suf[i]=(rs.suf[i]?rs.suf[i]:ls.suf[i]);}for(int i=30;i>=0;i--){if(!ls.suf[i]&&!rs.pre[i]){if(digit[i])break;continue;}int _L=min(L,ls.suf[i]),_R=max(R,rs.pre[i]);if(digit[i]){if(!ls.suf[i])R=_R;else if(!rs.pre[i])L=_L;else{if(st.query(_L,ls.r)<st.query(rs.l,_R))L=_L;else R=_R;}}else{if(!ls.suf[i])ret.v=min(ret.v,st.query(L,_R));else if(!rs.pre[i])ret.v=min(ret.v,st.query(_L,R));else ret.v=min({ret.v,st.query(L,_R),st.query(_L,R)});}}return ret;
}

代码:

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define endl '\n'
#define fastio ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
const int N=2e5+5;
const int INF=0x3f3f3f3f;
int n,v,a[N],b[N];
bool digit[50];struct ST{int f[21][N];void init(int *a,int n){rep(i,1,n)f[0][i]=a[i];for(int j=1;j<=20;j++)for(int i=1;i+(1<<j)-1<=n;i++)f[j][i]=max(f[j-1][i],f[j-1][i+(1<<(j-1))]);}int query(int l,int r){int k=__lg(r-l+1);return max(f[k][l],f[k][r+1-(1<<k)]);}
}st;
struct sgt{int suf[31],pre[31];int v,l,r;sgt(){memset(suf,0,sizeof(suf));memset(pre,0,sizeof(pre));v=INF;}
};
sgt operator +(const sgt &ls,const sgt &rs){sgt ret;int L=ls.r;ret.l=ls.l;int R=rs.l;ret.r=rs.r;ret.v=min(ls.v,rs.v);for(int i=30;i>=0;i--){ret.pre[i]=(ls.pre[i]?ls.pre[i]:rs.pre[i]);ret.suf[i]=(rs.suf[i]?rs.suf[i]:ls.suf[i]);}for(int i=30;i>=0;i--){if(!ls.suf[i]&&!rs.pre[i]){if(digit[i])break;continue;}int _L=min(L,ls.suf[i]),_R=max(R,rs.pre[i]);if(digit[i]){if(!ls.suf[i])R=_R;else if(!rs.pre[i])L=_L;else{if(st.query(_L,ls.r)<st.query(rs.l,_R))L=_L;else R=_R;}}else{if(!ls.suf[i])ret.v=min(ret.v,st.query(L,_R));else if(!rs.pre[i])ret.v=min(ret.v,st.query(_L,R));else ret.v=min({ret.v,st.query(L,_R),st.query(_L,R)});}}return ret;
}
struct segT{sgt tr[N<<2];#define ls (node<<1)#define rs (node<<1|1)void push_up(int node){tr[node]=tr[ls]+tr[rs];}void cl(sgt &p,int x){for(int i=30;i>=0;i--)p.suf[i]=p.pre[i]=(((b[x]>>i)&1)?x:0);p.v=(b[x]>v?a[x]:INF);p.l=p.r=x;}void build(int node,int l,int r){if(l==r){cl(tr[node],l);return;}int mid=(l+r)>>1;build(ls,l,mid);build(rs,mid+1,r);push_up(node);}void modify(int node,int l,int r,int x,int val){if(l==r){b[l]=val;cl(tr[node],l);return;}int mid=(l+r)>>1;if(mid>=x)modify(ls,l,mid,x,val);else modify(rs,mid+1,r,x,val);push_up(node);}sgt query(int node,int l,int r,int ql,int qr){if(ql<=l&&r<=qr)return tr[node];int mid=(l+r)>>1;if(mid<ql)return query(rs,mid+1,r,ql,qr);if(mid+1>qr)return query(ls,l,mid,ql,qr);return query(ls,l,mid,ql,qr)+query(rs,mid+1,r,ql,qr);}
}seg;
int main(){fastio;int tc;cin>>tc;while(tc--){cin>>n>>v;v--;for(int i=30;i>=0;i--)digit[i]=((v>>i)&1);rep(i,1,n)cin>>a[i];rep(i,1,n)cin>>b[i];st.init(a,n);seg.build(1,1,n);int q;cin>>q;while(q--){int op,i,x,l,r;cin>>op;if(op==1){cin>>i>>x;seg.modify(1,1,n,i,x);}else{cin>>l>>r;int ans=seg.query(1,1,n,l,r).v;if(ans==INF)cout<<-1<<' ';else cout<<ans<<' ';}}cout<<endl;}return 0;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/742384.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

去哪儿故障定位

https://mp.weixin.qq.com/s/9f9PUUy8c-GCJLa0deIvuA

Cilium DSR 特性(转载)

Cilium DSR 特性Cilium DSR(转载) 一、环境信息主机 IPubuntu 10.0.0.234软件 版本docker 26.1.4helm v3.15.0-rc.2kind 0.18.0kubernetes 1.23.4ubuntu os Ubuntu 22.04.6 LTSkernel 5.15.0-106 内核升级文档使用 5.11.5 内核版本的 20.04 版本,发起 curl 请求无法代理到 p…

上传恶意代码服务器和数据库的操作

在通过访问端对服务器上传一句话木马的时候,我们需要对服务器进行部分操作: 1.打开服务器远程目录权限: (1)在windows服务器上,将文件夹的只读方式去掉; (2)在linux服务器上,将文件夹的权限改为pwd 2.开启数据库secure_file_priv权限 (1)我这里使用的是mysql5.7.2…

Zabbix 5.0 LTS URL 健康监测

更多细节详情看【zabbix官方文档】 需求 Zabbix 的URL健康监测功能允许你检测 Web 地址是否可用、正常工作以及响应速度。这对于监控网站的可用性和性能非常有用。例如,你可以监控公司网站、API 端点或其他关键服务的 URL。【官方表述 Web monitoring items】【官方表述 Trigg…

idea 修改 git 提交用户名

本项目 修改配置文件 修改当前项目目录下的 config 文件添加以下数据[user]name = **email = **@gmail.com全局修改 git config --global user.name gitlab注册用户名 git config --global user.email gitlab注册邮箱

ChatMoney,你的就业指导明灯

本文由 ChatMoney团队出品介绍说明 Hey!亲爱的小伙伴们,今天我要给大家带来一个职场利器——AI就业指导机器人!🤖 在这个充满变数的职场江湖,找到一份既能养家糊口又能实现自我价值的工作是多么重要。但是,职业道路上的选择和决策并不总是那么容易。有时候,我们需要的不…

AI就业指导机器人,你的专属职业导航灯!

本文由 ChatMoney团队出品介绍说明 Hey!亲爱的小伙伴们,今天我要给大家带来一个职场利器——AI就业指导机器人!🤖 在这个充满变数的职场江湖,找到一份既能养家糊口又能实现自我价值的工作是多么重要。但是,职业道路上的选择和决策并不总是那么容易。有时候,我们需要的不…

IDEA工具使用Git回滚代码

回滚已经commit但未push到远程仓库的代码点击git,然后右键选择你要退回的那条记录,选择undo commit(撤销提交) ,代码回滚就完成了! 此操作只是回滚,并不会删除你的操作内容回滚已经push到远程仓库的代码1. 先回滚提交到本地仓库的代码选择需要回滚到那个版本的提交记录,右键…

转-Java 异常处理的 20 个最佳实践,你知道几个?

‍ 作  者:武培轩 出  处:https://www.cnblogs.com/wupeixuan 原文链接:https://www.cnblogs.com/wupeixuan/p/11746117.html 异常处理是 Java 开发中的一个重要部分,是为了处理任何错误状况,比如资源不可访问,非法输入,空输入等等。Java 提供了几个异常处理特性,以…

vue 混合方法mixins 协可以写入公共的方法

新建一个文件夹mixins 同views 同级export default {data() {return {};},mounted() {},methods: {// 修改标题方法ready(callback) {// 如果 jsbridge 已经注入则直接调用if (window.AlipayJSBridge) {callback && callback();} else {// 如果没有注入则监听注入的事…

小白记录Java后端学习遇到的问题

在访问swagger接口测试工具时,进不去在用 localhost 访问的地址的时候出现访问不到的问题,但是把 localhost 换成本地的地址 却可以访问到, 我心想localhost不就是我本地的地址嘛,解决: 发现如果设置了地址 就不能通过localhost访问到 如果不设置默认的话, 就可以访问 ht…

小红书卡片生成,使用W外链制作小红书卡片

在数字营销和社交媒体盛行的今天,小红书以其独特的社区氛围和购物推荐功能,成为了众多品牌和个人推广产品、分享经验的热门平台。而W外链作为一种高效的链接工具,能够帮助用户快速创建小红书卡片,实现内容的高效传播。本文将详细介绍如何使用W外链制作小红书卡片,并分享一…