挺不错的一道数据结构题QWQ。

一开始发现这个题如果不看数据范围的话,妥妥的树上莫队啊23333,然鹅10组数据是不可能让你舒舒服服的树上莫队卡过的23333

于是想了想,这个题的模型就是,把u到v链上的权值出现奇偶次的01串搞出来,然后第一个0的位置就是所求。。。。。

但是这个01串并不是很好搞,因为每一位都得异或啊。。。。这样复杂度就要乘上一个 200000/32了(bitset压位),还不如树上莫队呢QWQ

不过有一种套路,叫做hash异或,我们就给每一个权值随机一个unsined long long范围的hash值,大概率保证询问涉及的子集的异或和不为0(这个主要看人品了。。。因为总的来说肯定会有很多子集的异或和为0,但是因为子集总数太过庞大,询问涉及的只是小部分,所以出错概率还是很小的2333)

这样,如果一个区间所有数都出现奇数次,那么区间的hash异或起来就和 路径权值线段树在这个区间异或起来的值一样了,直接在主席树上二分即可。。。

(注意lca是要被算上的,但是如果直接用到根前缀的两个主席树异或的话lca是会被消去的)

#include<bits/stdc++.h>
#define ll unsigned long long
using namespace std;
const int maxn=200005;
#define mid (l+r>>1)
int T,n,a[maxn],m,to[maxn*2],ne[maxn*2],dep[maxn],le,w,A,B,ans;
int hd[maxn],num,siz[maxn],son[maxn],cl[maxn],f[maxn],ri,lca;
inline void add(int x,int y){ to[++num]=y,ne[num]=hd[x],hd[x]=num;}
ll val[maxn],Xor[maxn],now;
struct node{
ll sum;
node *lc,*rc;
}nil[maxn*37],*rot[maxn],*cnt; inline void init(){
nil->sum=0;
nil->lc=nil->rc=rot[0]=cnt=nil;
fill(hd+1,hd+n+1,0),num=0;
memset(son,0,sizeof(son));
} node *update(node *u,int l,int r){
node *ret=++cnt;
*ret=*u,ret->sum^=val[le];
if(l==r) return ret; if(le<=mid) ret->lc=update(ret->lc,l,mid);
else ret->rc=update(ret->rc,mid+1,r); return ret;
} void query(node *u,int l,int r){
if(l>=le&&r<=ri){ now^=u->sum; return;}
if(le<=mid) query(u->lc,l,mid);
if(ri>mid) query(u->rc,mid+1,r);
} void Fdfs(int x,int fa){
f[x]=fa,siz[x]=1,dep[x]=dep[fa]+1;
le=a[x],rot[x]=update(rot[fa],1,200001); for(int i=hd[x];i;i=ne[i]) if(to[i]!=fa){
Fdfs(to[i],x),siz[x]+=siz[to[i]];
if(!son[x]||siz[to[i]]>siz[son[x]]) son[x]=to[i];
}
} void Sdfs(int x,int tp){
cl[x]=tp;
if(!son[x]) return; Sdfs(son[x],tp);
for(int i=hd[x];i;i=ne[i]) if(to[i]!=f[x]&&to[i]!=son[x]) Sdfs(to[i],to[i]);
} int LCA(int x,int y){
while(cl[x]!=cl[y]){
if(dep[cl[x]]>dep[cl[y]]) x=f[cl[x]];
else y=f[cl[y]];
}
return dep[x]<dep[y]?x:y;
} void query(node *u,node *v,int l,int r){
if(l==r){ ans=l; return;} if((u->lc->sum^v->lc->sum^((a[lca]>=l&&a[lca]<=mid)?val[a[lca]]:0))==(Xor[mid]^Xor[l-1])) query(u->rc,v->rc,mid+1,r);
else query(u->lc,v->lc,l,mid);
} inline void solve(){
Fdfs(1,0),Sdfs(1,1); while(m--){
scanf("%d%d",&A,&B),lca=LCA(A,B);
query(rot[A],rot[B],1,200001);
printf("%d\n",ans);
}
} int main(){
// freopen("data.in","r",stdin);
// freopen("data.out","w",stdout); val[1]=1;
for(int i=2;i<=200001;i++) val[i]=val[i-1]*233ll;
for(int i=1;i<=200001;i++) Xor[i]=val[i]^Xor[i-1]; scanf("%d",&T);
while(T--){
init(),scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",a+i);
int uu,vv;
for(int i=1;i<n;i++) scanf("%d%d",&uu,&vv),add(uu,vv),add(vv,uu); solve();
} return 0;
}

[Lydsy1805月赛] 对称数的更多相关文章

  1. 【主席树上二分】bzoj5361: [Lydsy1805月赛]对称数

    随机化选讲例题 题目大意 小 Q 认为,偶数具有对称美,而奇数则没有.给定一棵 n 个点的树,任意两点之间有且仅有一条直接或间接路径.这些点编号依次为 1 到 n,其中编号为 i 的点上有一个正整数 ...

  2. BZOJ5361[Lydsy1805月赛]对称数——主席树+随机化

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=5361 好神的一道题啊! 容易看出来是要用维护权值的数据结构,因此树链剖分首先pass掉. ...

  3. [Lydsy1805月赛]对称数 BZOJ5361

    分析: 这个题,还是蛮有趣的.考虑,如果l,r区间内的所有数出现奇数次,那么[l-1,r]的抑或和等于所得抑或和. 之后怎么维护呢,主席树维护区间抑或和,记得将每个点附上一个ull级别的随机数,之后抑 ...

  4. [BZOJ5361][Lydsy1805月赛]对称数

    bzoj Description 给你一棵树,每个点有一个编号\(a_i\).\(Q\)组询问,每次问一条路径上最小的出现了偶数次的编号是多少(包括零次). 多组数据,\(T\le10,n,Q,a_i ...

  5. [Bzoj5358][Lydsy1805月赛]口算训练(预处理+动态开点线段树)

    5358: [Lydsy1805月赛]口算训练 Time Limit: 5 Sec  Memory Limit: 512 MBSubmit: 318  Solved: 105[Submit][Stat ...

  6. [LeetCode] Strobogrammatic Number III 对称数之三

    A strobogrammatic number is a number that looks the same when rotated 180 degrees (looked at upside ...

  7. [LeetCode] Strobogrammatic Number II 对称数之二

    A strobogrammatic number is a number that looks the same when rotated 180 degrees (looked at upside ...

  8. [LeetCode] Strobogrammatic Number 对称数

    A strobogrammatic number is a number that looks the same when rotated 180 degrees (looked at upside ...

  9. [BZOJ5361]/[HDU6291]对称数

    [BZOJ5361]/[HDU6291]对称数 题目大意: 一个\(n(n\le2\times10^5)\)个结点的树,每个结点有一个权值\(a_i(a_i\le2\times10^5)\),\(m( ...

随机推荐

  1. taotao购物车

    功能分析: 1.在用户不登陆的情况下也可以使用购物车,那么就需要把购物车信息放入cookie中. 2.可以把商品信息,存放到pojo中,然后序列化成json存入cookie中. 3.取商品信息可以从c ...

  2. Codis+redis 集群测试

    Codis 是一个分布式 Redis 解决方案, 对于上层的应用来说, 连接到 Codis Proxy 和连接原生的 Redis Server 没有显著区别 (不支持的命令列表), 上层应用可以像使用 ...

  3. 使用eclipse插件创建一个web project

    使用eclipse插件创建一个web project 首先创建一个Maven的Project如下图 我们勾选上Create a simple project (不使用骨架) 这里的Packing 选择 ...

  4. Installing Jenkins to Centos Docker

    1.Install Docker CE to Centos7 [root@zoo1 ~]# yum install -y yum-utils device-mapper-persistent-data ...

  5. ContenOS 安装配置 rpm 版本 Jenkins

    软件准备: jenkins-2.7.4-1.1.noarch.rpm java环境 安装jenkins: [root@localhost modules]# rpm -ih jenkins-2.7.4 ...

  6. es6+最佳入门实践(14)

    14.模版字符串 模版字符串(template string)是增强版的字符串,定义一个模版字符串需要用到反引号 let s = `这是一个模版字符串` console.log(s) 14.1.模版字 ...

  7. 链接oracle数据库 生成表对应的javabean

    package com.databi.utils; import java.io.File; import java.io.FileOutputStream; import java.io.IOExc ...

  8. struts学习笔记(四)

    一. 文件的上传: 1). 表单需要注意的 3 点 2). Struts2 的文件上传实际上使用的是 Commons FileUpload 组件, 所以需要导入 commons-fileupload- ...

  9. swift中_的用法,忽略默认参数名。

    swift中默认参数名除了第一个之外,其他的默认是不忽略的,但是如果在参数的名字前面加上_,就可以忽略这个参数名了,虽然有些麻烦,但是这种定义也挺好,而且不想知道名字或者不想让别人知道名字的或者不用让 ...

  10. 【洛谷 P1666】 前缀单词 (Trie)

    题目链接 考试时暴搜50分...其实看到"单词","前缀"这种字眼时就要想到\(Trie\)的,哎,我太蒻了. 以一个虚点为根,建一棵\(Trie\),然后\( ...