当前位置: 首页 > news >正文

P4592 TJOI2018 异或

题目

思路

这题看了好久,一直在不理解构建树链剖分的作用,以及构建可持续字典树的作用卡壳.
为什么要构建树链剖分:
寻找子树,简单路径,以及需要我们寻找树上的每个节点权值
可持续字典树:
在我们树链剖分时,我们会按照根节点,重儿子节点,轻儿子节点顺序遍历,那么,我们在添加节点的时候,我们也优先按照根节点,重儿子节点,轻儿子节点的顺序添加节点.我们可以在树剖时候,可以将每次添加节点的顺序记录出来,比如添加的节点为2,这是我们添加的第i个,我们就定义一个数组a[i]=2,再添加一个数组b,可以用来记录节点2对应的i值.之后,在插入构建root时就按照添加的顺序来
我们接着在分析问题:

  • 1 x z:查询节点 x 的子树中的节点权值与 z 异或结果的最大值。
  • 2 x y z:查询节点 x 到节点 y 的简单路径上的节点的权值与 z 异或结果最大值。
    根据我们构建的可持续化字典树
    问题1:我们就可以通过将x节点转化成对应的b,
    由于我们是根据根节点的顺序进行构建线段树,所以x最后一个子节点对应的添加次数就是b+size[x],因此问题1,就可以通过对root[b+size[x]]与root[b-1]的查询解决问题
    问题2:
    操作1: 我们先考虑两个节点x,y(y深度保持大于x)在同一条重链上的情况,此时重链就为简单路径,此时我们可以直接通过
    root[bx-1]与root[by]

操作2:如果不在一条链上,我们也先考虑深度大的,对深度大的操作,我们也可以先对y节点对应的重链头部进行操作1(该重链操作完毕),之后,在将y节点转化成重链头部的父节点(上一条重链),再次进行操作2直到两个节点都在同一条重链上
![[Pasted image 20251029123428.png]]

我们假设 1,2,3…为对应的节点
1,2,4为一条重链
3为一条重链
5,7为一条重链
6为一条重链
我们现在查找3,6之间最短路径节点权值与x的异或最小值
这里,我们先将3自己的权值与x进行异或,接着,再将6对应的权重与x进行异或,然后,再将1,2,4这条重链上的2,1节点权重与x分别进行异或,之后将5,7这条重链上的5的权重与x进行异或,现在我们发现此时x,y对应的值都为1,跳出循环,直接将1的权重与x进行异或

注:这里的异或说的比较简单,实际上是需要通过可持续化字典树通过上述的操作1进行查阅.

代码

#include<iostream>#include<string>#include<algorithm>#include<vector>using namespace std;const int N=1e5+10;int n,m;int a[N];vector<int>vec[N];int cnt;int id[N];//节点对应的cntint son[N];int f[N];int dep[N];int sz[N];int top[N];int val[N];void dfs(int u,int fa){sz[u]=1;f[u]=fa;dep[u]=dep[fa]+1;for(int i=0;i<vec[u].size();i++){int v=vec[u][i];if(v==fa)continue;dfs(v,u);sz[u]+=sz[v];if(sz[son[u]]<sz[v])son[u]=v;}}void dfs2(int u,int t){top[u]=t;id[u]=++cnt;val[cnt]=a[u];
//一定不要忘记返回这个条件if(!son[u])return;dfs2(son[u],t);for(int i=0;i<vec[u].size();i++){int v=vec[u][i];if(v==son[u])continue;if(v==f[u])continue;dfs2(v,v);}}int tot=0;int size[N*35];int root[N*35];int ch[N*35][2];void insert(int u,int v,int p){for(int i=29;i>=0;i--){int w=(p>>i&1);ch[u][!w]=ch[v][!w];ch[u][w]=++tot;size[ch[u][w]]=size[ch[v][w]]+1;u=ch[u][w];v=ch[v][w];}    }int query(int u,int v,int p){int res=0;for(int i=29;i>=0;i--){int w=(p>>i&1);if(size[ch[u][!w]]>size[ch[v][!w]]){res+=(1<<i);u=ch[u][!w];v=ch[v][!w];}else{u=ch[u][w];v=ch[v][w];}}return res;  }int query_range(int a,int b,int p){int res=0;int fa=top[a];int fb=top[b];while(fa!=fb){if(dep[fa]<dep[fb]){swap(fa,fb);swap(a,b);}
//这里,祖节点建立的早,所以是祖节点线段树的上一个,即root[id[fa]-1],我在这里最开始把祖节点和子节点建立顺序弄反了,调了好长时间res=max(res,query(root[id[a]],root[id[fa]-1],p));a=f[fa];fa=top[a];}if(dep[a]<dep[b])swap(a,b);res=max(res,query(root[id[a]],root[id[b]-1],p));return res;}int main(void){cin>>n>>m;for(int i=1;i<=n;i++)cin>>a[i];for(int i=1;i<=n-1;i++){int a,b;cin>>a>>b;vec[a].push_back({b});vec[b].push_back({a});}dfs(1,1);dfs2(1,1);for(register int i = 1 ; i <= n ; i ++) root[i] = ++ tot , insert(root[i] ,root[i - 1],val[i]) ;for(int i=1;i<=m;i++){int opt;cin>>opt;if(opt==1){int a,b;cin>>a>>b;cout<<query(root[id[a]+sz[a]-1],root[id[a]-1],b)<<endl;}else{int a,b,k;cin>>a>>b>>k;cout<<query_range(a,b,k)<<endl;}}}
http://www.dtcms.com/a/554521.html

相关文章:

  • 案例应聘网络营销做网站推广十大免费软件免费下载
  • Java 学习30:JavaBean 类、测试类与工具类
  • 菏泽网站建设菏泽wordpress顶部栏
  • 网站项目需求文档微信指数查询入口
  • 03_FastMCP 2.x 中文文档之FastMCP快速入门
  • 网站建设化学图片织梦协会网站模板
  • 帝国网站管理系统 数据库阿城区建设小学网站
  • 哪里可以做免费网站百度seo关键词排名优化软件
  • 毕节市城乡建设局网站html5手机网站发布
  • linux之arm SMMUv3 STE表和CD表数据格式分析(3)
  • 云蝠智能VoiceAgent 2.0,四大功能让语音智能体更智能、更包容
  • 娱乐网站建设流程个人网页设计论文免费
  • 青岛市专业做网站的吗网络文章发布平台
  • 强化学习之入门笔记(三)
  • css - 实现三角形 div 容器,用css画一个三角形(提供示例源码)简单粗暴几行代码搞定!
  • 长沙 php企业网站系统新动力网站建设公司
  • 全流程开发智能体 一
  • wordpress怎么当站长淄博公司网站建设价格
  • 几分钟网站做渔网网站建设有哪些功能模块
  • 水利建设经济定额站网站专业网站设计联系电话
  • MySQL | 数据查询语言DQL数据过滤语法及实例
  • 网站设计中的用户体验成品视频直播软件推荐哪个好一点非周马加
  • C/C++ 中 void* 深度解析:从概念到实战
  • 提升网站访问速度百度免费发布信息
  • OpenSIP3.4 路由脚本之我见
  • php网站开发进程施工企业工作环境
  • 第1讲:为什么是Flutter?跨平台开发的现状与未来
  • 怎样做网站策划教育培训机构十大排名
  • 成都怎样制作公司网站产品营销网站建设
  • 百度网站链接提交入口做淘宝网店需要多少钱