【题解】hdu4757 【TJOI2018】异或
题目大意:有一颗树,有点权,每次询问:一条路径\(x->y\)中与\(z\)异或的最大值,或是以\(x\)为根的子树中与\(y\)异或的最大值。
树剖……还是算了。
观察到,子树的\(dfn\)序是连续的一段区间。于是我们可以预处理\(dfs\)序来解决这个问题。
第二问,我们可以求两点的最近公共祖先,做一个树上差分来实现。
维护两颗可持久化\(Trie.\)一个维护\(dfs\)序,一个维护\(x->root\).
当然\(HDU\)的那个题是没有第一个操作的,但是是多组询问。
\(HDU:\)
#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e5+10;
int n,m,siz[MAXN],dfn[MAXN],f[MAXN][25];
int dep[MAXN],head[MAXN<<1],tot,dfstime;
int pre[MAXN],a[MAXN];
struct edge{
int nxt,to;
}e[MAXN<<1];
inline void add(int x,int y){
e[++tot].to=y;
e[tot].nxt=head[x];
head[x]=tot;
}
struct Trie{
int son[MAXN<<5][2],ct[MAXN<<5],root[MAXN],cnt=1;
void Insert(int &rt,int x,int T){
ct[++cnt]=ct[rt]+1;
son[cnt][0]=son[rt][0];
son[cnt][1]=son[rt][1];
rt=cnt;
if(T==-1)return;
bool y=(x>>T)&1;
Insert(son[rt][y],x,T-1);
}
void Ins(int pre,int rt,int x){
root[rt]=root[pre];
Insert(root[rt],x,30);
}
int Q(int i,int j,int x,int T){
if(T==-1)return 0;
int y=(x>>T)&1;
if(ct[son[j][1^y]]>ct[son[i][1^y]])return ((1<<T)+Q(son[i][1^y],son[j][1^y],x,T-1));
return Q(son[i][y],son[j][y],x,T-1);
}
int QT(int i,int j,int lc,int flc,int x,int T){
if(T==-1)return 0;
int y=(x>>T)&1;
if(ct[son[i][1^y]]+ct[son[j][1^y]]>ct[son[lc][1^y]]+ct[son[flc][1^y]])return ((1<<T)+QT(son[i][1^y],son[j][1^y],son[lc][1^y],son[flc][1^y],x,T-1));
else return QT(son[i][y],son[j][y],son[lc][y],son[flc][y],x,T-1);
}
int query(int i,int j,int x){
return Q(root[i-1],root[j],x,30);
}
int UQT(int i,int j,int lc,int flc,int x){
return QT(root[i],root[j],root[lc],root[flc],x,30);
}
void clear(){
cnt=1;
memset(root,0,sizeof(root));
memset(ct,0,sizeof(ct));
memset(son,0,sizeof(son));
}
}tr1;
void dfs(int u,int fa){
dep[u]=dep[fa]+1;siz[u]=1;
pre[dfn[u]=++dfstime]=u;
f[u][0]=fa;
for(int i=1;i<=22;++i)f[u][i]=f[f[u][i-1]][i-1];
tr1.Ins(fa,u,a[u]);
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(v==fa)continue;
dfs(v,u);siz[u]+=siz[v];
}
}
int LCA(int u,int v){
if(dep[u]<dep[v])u^=v^=u^=v;
for(int i=22;i>=0;--i)
if(dep[f[u][i]]>=dep[v])u=f[u][i];
if(u==v)return u;
for(int i=22;i>=0;--i)
if(f[u][i]!=f[v][i])
u=f[u][i],v=f[v][i];
return f[u][0];
}
void work(){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
int A=LCA(x,y);
printf("%d\n",tr1.UQT(x,y,A,f[A][0],z));
}
int main(){
while(~scanf("%d%d",&n,&m)){
for(int i=1;i<=n;++i)scanf("%d",&a[i]);
for(int i=1;i<n;++i){
int u,v;
scanf("%d%d",&u,&v);
add(u,v);add(v,u);
}
dfs(1,0);
for(;m;m--)work();
memset(a,0,sizeof(a));
dfstime=0;tot=0;
memset(dfn,0,sizeof(dfn));
memset(pre,0,sizeof(pre));
memset(dep,0,sizeof(dep));
memset(siz,0,sizeof(siz));
memset(f,0,sizeof(f));
memset(head,0,sizeof(head));
tr1.clear();
}
return 0;
}
\(Luogu:\)
#include<bits/stdc++.h>
using namespace std;
const int MAXN=2e5+10;
inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')w=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=(s<<1)+(s<<3)+(ch^48);
ch=getchar();
}
return w==-1?-s:s;
}
int n,m,dep[MAXN],a[MAXN],siz[MAXN],dfn[MAXN];
int tot,ktot,head[MAXN<<1],pre[MAXN],f[MAXN][25];
struct edge{
int nxt,to;
}e[MAXN<<1];
inline void add(int x,int y){
e[++tot].to=y;
e[tot].nxt=head[x];
head[x]=tot;
}
struct Trie{
int son[MAXN<<5][2],cnt=1,root[MAXN],ct[MAXN<<5];
void Insert(int &rt,int x,int T){
ct[++cnt]=ct[rt]+1,son[cnt][0]=son[rt][0];
son[cnt][1]=son[rt][1];rt=cnt;
if(T==-1)return;
bool y=(x>>T)&1;
Insert(son[rt][y],x,T-1);
}
inline void Ins(int pre,int rt,int x){
root[rt]=root[pre];
Insert(root[rt],x,30);
}
int Q(int i,int j,int x,int T){
if(T==-1)return 0;
bool y=(x>>T)&1;
if(ct[son[j][1^y]]>ct[son[i][1^y]])return ((1<<T)+Q(son[i][1^y],son[j][1^y],x,T-1));
return Q(son[i][y],son[j][y],x,T-1);
}
int QT(int i,int j,int lc,int flc,int x,int T){
if(T==-1)return 0;
bool y=(x>>T)&1;
if(ct[son[j][1^y]]+ct[son[i][1^y]]>ct[son[lc][1^y]]+ct[son[flc][1^y]])return ((1<<T)+QT(son[i][1^y],son[j][1^y],son[lc][1^y],son[flc][1^y],x,T-1));
else return QT(son[i][y],son[j][y],son[lc][y],son[flc][y],x,T-1);
}
int query(int l,int r,int x){return Q(root[l-1],root[r],x,30);}
int UQT(int i,int j,int lc,int flc,int x,int T){
return QT(root[i],root[j],root[lc],root[flc],x,T);
}
}tr1,tr2;
void dfs(int u,int fa){
dep[u]=dep[fa]+1;f[u][0]=fa;
dfn[u]=++ktot;pre[ktot]=u;
tr1.Ins(fa,u,a[u]);siz[u]=1;
for(int i=1;i<=22;++i)f[u][i]=f[f[u][i-1]][i-1];
for(int i=head[u];i;i=e[i].nxt){
int j=e[i].to;
if(j==fa)continue;
dfs(j,u);siz[u]+=siz[j];
}
}
int LCA(int x,int y){
if(dep[x]<dep[y])swap(x,y);
for(int i=22;i>=0;--i)
if(dep[f[x][i]]>=dep[y])x=f[x][i];
if(x==y)return x;
for(int i=22;i>=0;--i)
if(f[x][i]!=f[y][i])
x=f[x][i],y=f[y][i];
return f[x][0];
}
int main(){
n=read(),m=read();
for(int i=1;i<=n;++i)a[i]=read();
for(int i=1;i<n;++i){
int u=read(),v=read();
add(u,v);add(v,u);
}
dfs(1,0);
for(int i=1;i<=n;++i)tr2.Ins(i-1,i,a[pre[i]]);
for(;m;--m){
int opt=read();
if(opt==1){
int x=read(),y=read();
printf("%d\n",tr2.query(dfn[x],dfn[x]+siz[x]-1,y));
}
else {
int x=read(),y=read(),z=read(),A=LCA(x,y);
printf("%d\n",tr1.UQT(x,y,A,f[A][0],z,30));
}
}
return 0;
}
【题解】hdu4757 【TJOI2018】异或的更多相关文章
- 【BZOJ5338】[TJOI2018]异或(主席树)
[BZOJ5338][TJOI2018]异或(主席树) 题面 洛谷 题解 很明显的是\(Trie\)树上暴力判断答案 因为要支持区间,用主席树的结构存\(Trie\)树就好了 #include< ...
- 洛谷 P4592 [TJOI2018]异或 解题报告
P4592 [TJOI2018]异或 题目描述 现在有一颗以\(1\)为根节点的由\(n\)个节点组成的树,树上每个节点上都有一个权值\(v_i\).现在有\(Q\)次操作,操作如下: 1 x y:查 ...
- BZOJ5338:[TJOI2018]异或——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=5338 现在有一颗以1为根节点的由n个节点组成的树,树上每个节点上都有一个权值vi. 现在有Q 次操 ...
- 洛谷 P4592: bzoj 5338: [TJOI2018]异或
题目传送门:洛谷P4592. 题意简述: 题面说的很清楚了. 题解: 发现没有修改很快乐.再看异或最大值操作,很容易想到可持久化 01trie. 这里要把 01trie 搬到树上,有点难受. 树剖太捞 ...
- [洛谷P4592][TJOI2018]异或
题目大意:有一棵$n$个点的树,第$i$个点权值为$w_i$,有两种操作: $1\;x\;y:$询问节点$x$的子树中与$y$异或结果的最大值 $2\;x\;y\;z:$询问路径$x$到$y$上点与$ ...
- P4592 [TJOI2018]异或 (可持久化Trie)
[题目链接] https://www.luogu.org/problemnew/show/P4592 题目描述 现在有一颗以\(1\)为根节点的由\(n\)个节点组成的树,树上每个节点上都有一个权值\ ...
- 【题解】kth异或和/魔改版线性基
[题解]魔改版线性基 魔改版线性基解决此类问题. 联系线性空间的性质,我们直接可以构造出这样的基: \[ 100000 \\ 010000 \\ 000010 \\ 000001 \] 使得每个基的最 ...
- [TJOI2018]异或
Description: 现在有一颗以1为根节点的由n个节点组成的树,树上每个节点上都有一个权值v 现在有Q次操作,操作如下: 1.1 x y :查询节点x的子树中与y异或结果的最大值 2.2 x ...
- 可持久化01Trie树+LCA【p4592】[TJOI2018]异或
Description 现在有一颗以\(1\)为根节点的由\(n\)个节点组成的树,树上每个节点上都有一个权值\(v_i\).现在有\(Q\)次操作,操作如下: 1\(\;x\;y\):查询节点\(x ...
- 洛谷P4592 [TJOI2018]异或 【可持久化trie树】
题目链接 BZOJ4592 题解 可持久化trie树裸题 写完就A了 #include<algorithm> #include<iostream> #include<cs ...
随机推荐
- Linux+Jenkins自动构建服务器包
何时使用: 测试过程中我们需要持续构建一个软件项目,为避免重复的手动下载.解压操作,我们需要搭建一个能够自动构建的测试环境,当代码有更新时,测试人员只需点一下[构建]即可拉取最新的代码进行测试(也可设 ...
- 【jmespath】—1. 基础用法
一.jsonpath 之前我写接口自动化测试时候,对于复杂的json返回,会使用jsonpath这个第三方库,就像写xpath一样,方便的查询json元素. 因为之前写WEB自动化时候,总用xpath ...
- Tomact的中文乱码设置
在使用Tomact时,有时候使用中文时,窗口会把中文部分显示为乱码,这时需要修改相关配置,让其正常显示. 1.修改server.xml的配置,解决显示窗口的乱码 打开Tomcat下/bin/serve ...
- SpringSecurity中的Authentication信息与登录流程
目录 Authentication 登录流程 一.与认证相关的UsernamePasswordAuthenticationFilter 获取用户名和密码 构造UsernamePasswordAuthe ...
- Tcahce Stashing Unlink Attack
今年校赛有点可惜,最后两道质量不错的pwn每做出来,总的来说还是我太菜了,希望下次校赛能AK pwn题.不过这次校赛也没有白打,还是有学到新的东西的.在这里感谢出题的学长. glibc-2.29以后u ...
- python日志模块配置
import logging logging.basicConfig(filename= 'out.log',filemode= 'w+', level= logging.DEBUG, format= ...
- postman测试接口
一.postman安装 不介绍.可百度搜索.安装完成后如下: 二.postman测试接口 get请求: post请求:请求参数如果是json格式,则如下 上传文件:如果接口中要求上传文件,可如下操作 ...
- centos7使用Minikube“快速搭建“出Kubernetes本地实验环境(踩坑集锦及解决方案)
先决条件(先假设你做完这两步骤) 检查Linux是否支持虚拟化,验证输出是否为非空如何开启虚拟化 grep -E --color 'vmx|svm' /proc/cpuinfo 安装 kubectl ...
- pytest测试框架 -- assert断言和fixture固件
一.断言 (1)使用assert语句进行断言 # test_run.py @pytest.mark.assert def test_assert(self): r = requests.get(&qu ...
- 每日一道 LeetCode (48):最长回文子串
每天 3 分钟,走上算法的逆袭之路. 前文合集 每日一道 LeetCode 前文合集 代码仓库 GitHub: https://github.com/meteor1993/LeetCode Gitee ...