BZOJ5338[TJOI2018]xor——主席树+dfs序
题目描述
输入
输出
样例输入
1 3 5 7 9 2 4
1 2
1 3
2 4
2 5
3 6
3 7
1 3 5
2 4 6 3
1 5 5
2 5 7 2
1 1 9
样例输出
6
12
11
14
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int cnt;
int num;
int tot;
int n,m;
int opt;
int res1;
int res2;
int x,y,z;
int v[100010];
int d[100010];
int s[100010];
int t[100010];
int to[200010];
int in[100010];
int out[100010];
int ioth[200010];
int head[100010];
int dfsth[100010];
int f[100010][17];
int next[200010];
int root1[200010];
int root2[200010];
int ls1[10000010];
int rs1[10000010];
int ls2[10000010];
int rs2[10000010];
int sum1[10000010];
int sum2[10000010];
void add(int x,int y)
{
tot++;
next[tot]=head[x];
head[x]=tot;
to[tot]=y;
}
void dfs(int x,int fa)
{
d[x]=d[fa]+1;
f[x][0]=fa;
in[x]=++cnt;
s[x]=++num;
ioth[cnt]=x;
dfsth[num]=x;
for(int i=1;i<=16;i++)
{
f[x][i]=f[f[x][i-1]][i-1];
}
for(int i=head[x];i;i=next[i])
{
if(to[i]!=fa)
{
dfs(to[i],x);
}
}
out[x]=++cnt;
t[x]=num;
ioth[cnt]=-x;
}
int lca(int x,int y)
{
if(d[x]<d[y])
{
swap(x,y);
}
int dep=d[x]-d[y];
for(int i=0;i<=16;i++)
{
if(((1<<i)&dep)!=0)
{
x=f[x][i];
}
}
if(x==y)
{
return x;
}
for(int i=16;i>=0;i--)
{
if(f[x][i]!=f[y][i])
{
x=f[x][i];
y=f[y][i];
}
}
return f[x][0];
}
int updata1(int pre,int k,int v)
{
int rt=++res1;
ls1[rt]=ls1[pre];
rs1[rt]=rs1[pre];
sum1[rt]=sum1[pre]+1;
if(k<0)
{
return rt;
}
if(((1<<k)&v)==0)
{
ls1[rt]=updata1(ls1[pre],k-1,v);
}
else
{
rs1[rt]=updata1(rs1[pre],k-1,v);
}
return rt;
}
int query1(int l,int r,int v,int k)
{
if(k<0)
{
return 0;
}
if(((1<<k)&v)==0)
{
if(sum1[rs1[r]]-sum1[rs1[l]]>0)
{
return query1(rs1[l],rs1[r],v,k-1)+(1<<k);
}
else
{
return query1(ls1[l],ls1[r],v,k-1);
}
}
else
{
if(sum1[ls1[r]]-sum1[ls1[l]]>0)
{
return query1(ls1[l],ls1[r],v,k-1)+(1<<k);
}
else
{
return query1(rs1[l],rs1[r],v,k-1);
}
}
}
int updata2(int pre,int k,int v,int x)
{
int rt=++res2;
ls2[rt]=ls2[pre];
rs2[rt]=rs2[pre];
sum2[rt]=sum2[pre]+x;
if(k<0)
{
return rt;
}
if(((1<<k)&v)==0)
{
ls2[rt]=updata2(ls2[pre],k-1,v,x);
}
else
{
rs2[rt]=updata2(rs2[pre],k-1,v,x);
}
return rt;
}
int query2(int x,int y,int fa,int anc,int v,int k)
{
if(k<0)
{
return 0;
}
if(((1<<k)&v)==0)
{
if(sum2[rs2[x]]+sum2[rs2[y]]-sum2[rs2[fa]]-sum2[rs2[anc]]>0)
{
return query2(rs2[x],rs2[y],rs2[fa],rs2[anc],v,k-1)+(1<<k);
}
else
{
return query2(ls2[x],ls2[y],ls2[fa],ls2[anc],v,k-1);
}
}
else
{
if(sum2[ls2[x]]+sum2[ls2[y]]-sum2[ls2[fa]]-sum2[ls2[anc]]>0)
{
return query2(ls2[x],ls2[y],ls2[fa],ls2[anc],v,k-1)+(1<<k);
}
else
{
return query2(rs2[x],rs2[y],rs2[fa],rs2[anc],v,k-1);
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&v[i]);
}
for(int i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
dfs(1,0);
for(int i=1;i<=num;i++)
{
root1[i]=updata1(root1[i-1],30,v[dfsth[i]]);
}
for(int i=1;i<=cnt;i++)
{
root2[i]=updata2(root2[i-1],30,v[abs(ioth[i])],ioth[i]>0?1:-1);
}
for(int i=1;i<=m;i++)
{
scanf("%d",&opt);
if(opt==1)
{
scanf("%d%d",&x,&y);
printf("%d\n",query1(root1[s[x]-1],root1[t[x]],y,30));
}
else
{
scanf("%d%d%d",&x,&y,&z);
int anc=lca(x,y);
printf("%d\n",query2(root2[in[x]],root2[in[y]],root2[in[anc]],root2[in[f[anc][0]]],z,30));
}
}
}
BZOJ5338[TJOI2018]xor——主席树+dfs序的更多相关文章
- 51 nod 1681 公共祖先 (主席树+dfs序)
1681 公共祖先 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 有一个庞大的家族,共n人.已知这n个人的祖辈关系正好形成树形结构(即父亲向儿子连边). 在另 ...
- 【BZOJ1803】Spoj1487 Query on a tree III 主席树+DFS序
[BZOJ1803]Spoj1487 Query on a tree III Description You are given a node-labeled rooted tree with n n ...
- 【BZOJ-3545&3551】Peaks&加强版 Kruskal重构树 + 主席树 + DFS序 + 倍增
3545: [ONTAK2010]Peaks Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1202 Solved: 321[Submit][Sta ...
- 【SPOJ】10628. Count on a tree(lca+主席树+dfs序)
http://www.spoj.com/problems/COT/ (速度很快,排到了rank6) 这题让我明白了人生T_T 我知道我为什么那么sb了. 调试一早上都在想人生. 唉. 太弱. 太弱. ...
- BZOJ 2809: [Apio2012]dispatching [主席树 DFS序]
传送门 题意:查询树上根节点值*子树中权值和$\le m$的最大数量 最大值是多少 求$DFS$序,然后变成区间中和$\le m$最多有几个元素,建主席树,然后权值线段树上二分就行了 $WA$:又把边 ...
- BZOJ - 2809 dispatching 主席树+dfs序
在一个忍者的帮派里,一些忍者们被选中派遣给顾客,然后依据自己的工作获取报偿.在这个帮派里,有一名忍者被称之为 Master.除了 Master以外,每名忍者都有且仅有一个上级.为保密,同时增强忍者们的 ...
- BZOJ3772 精神污染 主席树 dfs序
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3772 题意概括 给出一个树,共n个节点. 有m条互不相同的树上路径. 现在让你随机选择2条路径,问 ...
- BZOJ3545&3551[ONTAK2010]Peaks——kruskal重构树+主席树+dfs序+树上倍增
题目描述 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询问询问从点v开始只 ...
- Codeforces 893F(主席树+dfs序)
在子树内和距离不超过k是一个二维限制,容易想到主席树,但主席树显然没法查最小值,因为不满足区间可减.kdtree和二维线段树可以干这事,但肯定会T飞.但事实上我们的问题有一个特殊性:对某个点x,查询其 ...
随机推荐
- 【Codeforces Round 1110】Codeforces Global Round 1
Codeforces Round 1110 这场比赛只做了\(A\).\(B\).\(C\),排名\(905\),不好. 主要的问题在\(D\)题上,有\(505\)人做出,但我没做出来. 考虑的时候 ...
- LeetCode202:Happy Number 。C#版,在vs2010中通过,leetcode中Wrong Answer
static List<int> nums = new List<int>(); public static bool IsHappy(int n) { int newint ...
- linux 资料
吾爱linux 摘自传智播客
- WebService与CXF
一:Webservice 1:WebService是干什么的?有什么用? 一言以蔽之:WebService是一种跨编程语言和跨操作系统平台的远程调用技术. 所谓跨编程语言和跨操作平台,就是说服务端程序 ...
- 把List<T>转换为DataTable
下面这个学习,把List<T>转换为Datatable. 下面先创建一个对象T: class Ay { private int _ID; public int ID { get { ret ...
- 使用awk按照行数切割文件
最近在做一个事情,需要将一个文本文件按照行数进行切割,然后用了,awk的方法,感觉很好用, 记录一下. 脚本如下: #!/bin/bash ## 文件效果: 根据行数来切割文件 ## 参数1为要切割的 ...
- [Spark][Python]DataFrame中取出有限个记录的例子
[Spark][Python]DataFrame中取出有限个记录的例子: sqlContext = HiveContext(sc) peopleDF = sqlContext.read.json(&q ...
- AtCoder ExaWizards 2019 简要题解
AtCoder ExaWizards 2019 简要题解 Tags:题解 link:https://atcoder.jp/contests/exawizards2019 很水的一场ARC啊,随随便便就 ...
- Unity3d之树木创建的参数设定
Unity3d之树木创建的参数设定 通常Unity3d创建树木经常会创建出很多奇葩的种类=_=,以下是创建出比较正常树木的基本参数 1:> 基本树干形状建立: 选择根建立分枝干设置分支干Di ...
- Flutter - Json序列化
这个问题,FlutterChina小组已经说明的非常清楚易懂了. 详见https://flutterchina.club/json/