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,查询其 ...
随机推荐
- Ubuntu触摸屏校准命令
1.sudo apt-get install utouch 2.sudo apt-get install xinput-calibrator 3.sudo xinput_calibrator(校准两次 ...
- Java中关于类型自动提升的两个注意点。
问题一:在进行赋值运算时,进行类型提升: 例如:short s1 = 1;s1 = s1 + 1; (错的编译通不过) short s2 = 1;s2 += 1;(正确,编译和运行都能通过) 为什么呢 ...
- OSGeo.OGR.Geometry
#region 程序集 ogr_csharp.dll, v2.0.50727 // D:\KM行业需求\C++\gdal17_cSharp\ogr_csharp.dll #endregion usin ...
- 不存在具有键“xxxId”的“IEnumerable<SelectListItem>”类型的 ViewData 项
项目中的某个页面,在访问时出现以下错误: 不存在具有键“xxxId”的“IEnumerable<SelectListItem>”类型的 ViewData 项 具体的场景说明如下: 一个编辑 ...
- 【第196期】Drupal7 Features模块与 Drupal8 Configuration Management 模块对比
Drupal 8 最好和最受欢迎的部分之一是新的配置管理系统. 该系统使开发人员很容易将配置导出到代码中.在此之前,开发人员不得不依赖于由Features.Strongarm.UUID.Feature ...
- VSCode Install Go
首先是VScode官网下载:https://code.visualstudio.com/ 然后在电脑上安装go的环境 如下图在VSCode上搜go的插件进行安装: 推荐:vscode-icons这个插 ...
- Ionic2 播放mp3功能实现
在开发app的过程中有需要播放mp3的功能,一直想实现,但苦于具体的困难一直未能实现,经过一段时间的资料查询和测试,最终摸索出来,现记录如下: 1.最重要的是安装第三方插件ionic-audio,开源 ...
- python基础学习笔记(十二)
模块 前面有简单介绍如何使用import从外部模块获取函数并且为自己的程序所用: >>> import math >>> math.sin(0) #sin为正弦函数 ...
- 浅谈JS的作用域链(一)
JS的执行环境 执行环境(Execution context,EC)或执行上下文,是JS中一个极为重要的概念. 在JavaScript中有三种代码运行环境: Global Code JavaScrip ...
- Python_初识函数和返回值_22
#len s = '金老板小护士' len(s) def my_len(): #自定义函数 i = 0 for k in s: i += 1 print(i) length = my_len() pr ...