【[TJOI2018]异或】
写板子了,可持久化\(Trie\)的板子了
其实和主席树写法类似,还是存好左右儿子之后存好权值
之后差分去查询就好了
这道题第一问我们直接\(dfs\)序转化成区间
第二问搞成\(x,y,lca(x,y),fa[lca]\)之后一起差分就好了
代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define maxn 100005
#define re register
#define LL long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
inline int read() {
char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();
return x;
}
struct E{int v,nxt;}e[maxn<<1];
int n,m,__,num,bit[35],cnt;
int rt[maxn],ch[maxn*35*2][2],v[maxn*35*2],a[maxn],Rt[maxn];
int head[maxn],top[maxn],son[maxn],sum[maxn],fa[maxn],to[maxn],_to[maxn],deep[maxn];
inline void add(int x,int y) {e[++num].v=y;e[num].nxt=head[x];head[x]=num;}
int change(int pre,int t) {
int root=++cnt;
int val=bit[t];
v[root]=v[pre]+1;
if(!t) return root;
ch[root][val^1]=ch[pre][val^1];
ch[root][val]=change(ch[pre][val],t-1);
return root;
}
int query(int l,int r,int t) {
if(!t) return 0;
int val=bit[t];
int now=v[ch[r][val^1]]-v[ch[l][val^1]];
if(now) return (1<<(t-1))+query(ch[l][val^1],ch[r][val^1],t-1);
return query(ch[l][val],ch[r][val],t-1);
}
int ask(int a,int b,int c,int d,int t) {
if(!t) return 0;
int val=bit[t];
int now=v[ch[a][val^1]]+v[ch[b][val^1]]-v[ch[c][val^1]]-v[ch[d][val^1]];
if(now) return (1<<(t-1))+ask(ch[a][val^1],ch[b][val^1],ch[c][val^1],ch[d][val^1],t-1);
return ask(ch[a][val],ch[b][val],ch[c][val],ch[d][val],t-1);
}
void dfs1(int x) {
int maxx=-1;sum[x]=1;
for(re int i=head[x];i;i=e[i].nxt)
if(!deep[e[i].v])
{
deep[e[i].v]=deep[x]+1;
int now=0,t=a[e[i].v];
memset(bit,0,sizeof(bit));
while(t) bit[++now]=(t&1),t>>=1;
Rt[e[i].v]=change(Rt[x],32);
fa[e[i].v]=x;dfs1(e[i].v);
sum[x]+=sum[e[i].v];
if(sum[e[i].v]>maxx) maxx=sum[e[i].v],son[x]=e[i].v;
}
}
void dfs2(int x,int topf) {
top[x]=topf;to[++__]=x;_to[x]=__;
if(!son[x]) return;
dfs2(son[x],topf);
for(re int i=head[x];i;i=e[i].nxt) if(!top[e[i].v]) dfs2(e[i].v,e[i].v);
}
inline int LCA(int x,int y) {
while(top[x]!=top[y])
{if(deep[top[x]]<deep[top[y]]) std::swap(x,y); x=fa[top[x]];}
if(deep[x]<deep[y]) return x;return y;
}
int main()
{
n=read(),m=read();
for(re int i=1;i<=n;i++) a[i]=read();
int x,y,opt,val;
for(re int i=1;i<n;i++) x=read(),y=read(),add(x,y),add(y,x);
deep[1]=1,dfs1(1),dfs2(1,1);
for(re int i=1;i<=n;i++)
{
int now=0,t=a[to[i]];
memset(bit,0,sizeof(bit));
while(t) bit[++now]=(t&1),t>>=1;
rt[i]=change(rt[i-1],32);
}
while(m--)
{
opt=read();x=read();
if(opt==1) val=read();
if(opt==2) y=read(),val=read();
int now=0;
memset(bit,0,sizeof(bit));
while(val) bit[++now]=(val&1),val>>=1;
if(opt==1) printf("%d\n",query(rt[_to[x]-1],rt[_to[x]+sum[x]-1],32));
if(opt==2) {int lca=LCA(x,y);printf("%d\n",ask(Rt[x],Rt[y],Rt[lca],Rt[fa[lca]],32));}
}
return 0;
}
【[TJOI2018]异或】的更多相关文章
- 【BZOJ5338】[TJOI2018]异或(主席树)
[BZOJ5338][TJOI2018]异或(主席树) 题面 洛谷 题解 很明显的是\(Trie\)树上暴力判断答案 因为要支持区间,用主席树的结构存\(Trie\)树就好了 #include< ...
- 洛谷 P4592 [TJOI2018]异或 解题报告
P4592 [TJOI2018]异或 题目描述 现在有一颗以\(1\)为根节点的由\(n\)个节点组成的树,树上每个节点上都有一个权值\(v_i\).现在有\(Q\)次操作,操作如下: 1 x y:查 ...
- [TJOI2018]异或
Description: 现在有一颗以1为根节点的由n个节点组成的树,树上每个节点上都有一个权值v 现在有Q次操作,操作如下: 1.1 x y :查询节点x的子树中与y异或结果的最大值 2.2 x ...
- 洛谷 P4592: bzoj 5338: [TJOI2018]异或
题目传送门:洛谷P4592. 题意简述: 题面说的很清楚了. 题解: 发现没有修改很快乐.再看异或最大值操作,很容易想到可持久化 01trie. 这里要把 01trie 搬到树上,有点难受. 树剖太捞 ...
- [洛谷P4592][TJOI2018]异或
题目大意:有一棵$n$个点的树,第$i$个点权值为$w_i$,有两种操作: $1\;x\;y:$询问节点$x$的子树中与$y$异或结果的最大值 $2\;x\;y\;z:$询问路径$x$到$y$上点与$ ...
- BZOJ5338:[TJOI2018]异或——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=5338 现在有一颗以1为根节点的由n个节点组成的树,树上每个节点上都有一个权值vi. 现在有Q 次操 ...
- 可持久化01Trie树+LCA【p4592】[TJOI2018]异或
Description 现在有一颗以\(1\)为根节点的由\(n\)个节点组成的树,树上每个节点上都有一个权值\(v_i\).现在有\(Q\)次操作,操作如下: 1\(\;x\;y\):查询节点\(x ...
- P4592 [TJOI2018]异或 (可持久化Trie)
[题目链接] https://www.luogu.org/problemnew/show/P4592 题目描述 现在有一颗以\(1\)为根节点的由\(n\)个节点组成的树,树上每个节点上都有一个权值\ ...
- 洛谷P4592 [TJOI2018]异或(可持久化01Trie)
题意 题目链接 可持久化01Trie板子题 对于两个操作分别开就行了 #include<bits/stdc++.h> using namespace std; const int MAXN ...
- P4592 [TJOI2018]异或
吐槽 睡起来写道模板清醒一下 貌似有两个log的树剖写法,还有一个log的Trie树的差分做法(类似于count on a tree),然后一个log的要把两个询问分开写,一个dfs序一个差分,然后我 ...
随机推荐
- python3 生成器笔记
#生成器def MyDemo(M): for i in range(M): yield i**2for item in MyDemo(9): print(item) # #生成器import sysa ...
- python解决excel工作薄合并处理
年度了,要对每个月的数据进行总的汇总,去计算每消耗品的使用情况,表格都在一个工作表的不同sheet中,并且格式相同,所以就用python写了这个小脚本,现在把脚本粘贴出来,以后有需要就可以在此基础上改 ...
- Java学习笔记day07_琐碎知识_水仙花数_ASCII码_冒泡排序_简单选择排序_折半查找
琐碎知识: 水仙花数, ASCII码, 冒泡排序, 简单选择排序, 折半查找 1.水仙花数 每位数的平方的和等于本身. 如100到999之间的水仙花数满足: 个位的平方+十位的平方+百位的平方 = 本 ...
- ios中页面底部输入框,position:fixed元素的问题
在安卓上点击页面底部的输入框,软键盘弹出,页面移动上移.ios上,软件盘弹出,输入框看不到了.让他弹出时让滚动条在最低部 var u = navigator.userAgent, app = navi ...
- java——删除链表中等于给定值的所有元素
class ListNode{ int val ; ListNode next; public ListNode(int x) { val = x; } public ListNode(int[] a ...
- my.资料
领回梦丹 http://ka.gamedog.cn/card/2036517.html 1. 普陀的加点没有优点缺点之分,只有是否和你的装备般配.这里可以给一些小数据参考. 60级物理防御达到900, ...
- python3与python2的区别 记录一波
1.性能 Py3.0运行 pystone benchmark的速度比Py2.5慢30%.Guido认为Py3.0有极大的优化空间,在字符串和整形操作上可 以取得很好的优化结果. Py3.1性能比Py2 ...
- git分布式的理解----简单服务端搭建
Git是分布式的,并没有服务端跟客户端之分,所谓的服务端安装的其实也是git.Git支持四种协议,file,ssh,git,http.ssh是使用较多的,下面使用ssh搭建一个免密码登录的服务端. 1 ...
- C++中string erase函数的使用
erase函数的原型如下:(1)string& erase ( size_t pos = 0, size_t n = npos );(2)iterator erase ( iterator p ...
- css 动画 和 响应式布局和兼容性
14.动画 -moz-:火狐, -ms-:IE,-webkit-:谷歌,-o-:欧朋 transform旋转 rotate旋转 scale放大 translate偏移量 skew倾斜度 transfo ...