随机化选讲例题

题目大意

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

定义集合 S(u, v) 为 u 点到 v 点的唯一最短路径上经过的所有点 x(包括 u 和 v) 对应的正整数 ax 的集合。小 Q 将在 m 个 S(u, v) 中寻找最小的对称数。因为偶数具有对称美,所以对称数是指那些出 现了偶数次 (包括 0 次) 的正整数。

请写一个程序,帮助小 Q 找到最小的对称数。

Input

第一行包含一个正整数 T (1 ≤ T ≤ 10),表示测试数据的组数。

每组数据第一行包含两个正整数 n, m(1 ≤ n, m ≤ 200000),分别表示点数和询问数。

第二行包含 n 个正整数 a1, a2, ..., an(1 ≤ ai ≤ 200000),依次表示每个点上的数字。

接下来 n − 1 行,每行两个正整数 ui,vi(1 ≤ ui,vi ≤ n,ui ̸= vi),表示一条连接 ui 和 vi 的双向树 边。

接下来 m 行,每行两个正整数 ui, vi(1 ≤ ui, vi ≤ n),依次表示每个询问。

Output

对于每个询问输出一行一个正整数,即最小的对称数。


题目分析

异或问题的处理套路,考虑权值的异或和是否为零。

具体来说,就是首先把$1\cdots 200000$各自随机一个ull的权值$val_i$,再使用树上建的主席树二分检查查询的路径$(u,v)$中的权值$[l,r]$:若$[l,mid]$的权值异或不等于$val_l \oplus val_{l+1} \cdots val_{mid}$,说明$[l,mid]$内至少有一个数出现了偶数次,那么就向$[l,mid]$层递归;$[mid+1,r]$同理。

其他也没什么细节,反正就是小数据结构练手题吧。

 #include<bits/stdc++.h>
typedef unsigned long long ull;
const int maxn = ;
const int maxm = ;
const int maxNode = ; struct node
{
int l,r;
ull val;
}f[maxNode];
ull val[maxn];
int n,m,tot,cnt,rt[maxn],a[maxn],dep[maxn],fat[maxn][];
int edgeTot,head[maxn],nxt[maxm],edges[maxm]; int read()
{
char ch = getchar();
int num = , fl = ;
for (; !isdigit(ch); ch=getchar())
if (ch=='-') fl = -;
for (; isdigit(ch); ch=getchar())
num = (num<<)+(num<<)+ch-;
return num*fl;
}
void addedge(int u, int v)
{
edges[++edgeTot] = v, nxt[edgeTot] = head[u], head[u] = edgeTot;
edges[++edgeTot] = u, nxt[edgeTot] = head[v], head[v] = edgeTot;
}
void update(int &rt, int pre, int l, int r, int c)
{
rt = ++tot;
f[rt] = f[pre], f[rt].val ^= val[c]^val[c-];
if (l==r) return;
int mid = (l+r)>>;
if (c <= mid) update(f[rt].l, f[pre].l, l, mid, c);
else update(f[rt].r, f[pre].r, mid+, r, c);
}
void dfs(int x, int fa)
{
fat[x][] = fa, dep[x] = dep[fa]+;
update(rt[x], rt[fa], , cnt, a[x]);
for (int i=head[x]; i!=-; i=nxt[i])
if (edges[i]!=fa) dfs(edges[i], x);
}
int lca(int u, int v)
{
if (dep[u] > dep[v]) std::swap(u, v);
for (int i=; i>=; i--)
if (dep[fat[v][i]] >= dep[u]) v = fat[v][i];
if (u==v) return u;
for (int i=; i>=; i--)
if (fat[u][i]!=fat[v][i]) u = fat[u][i], v = fat[v][i];
return fat[u][];
}
void query(int l, int r, int u, int v, int p, int q)
{
if (l==r) printf("%d\n",l);
else{
int mid = (l+r)>>;
if ((f[f[u].l].val^f[f[v].l].val^f[f[p].l].val^f[f[q].l].val)!=(val[mid]^val[l-]))
query(l, mid, f[u].l, f[v].l, f[p].l, f[q].l);
else query(mid+, r, f[u].r, f[v].r, f[p].r, f[q].r);
}
}
int main()
{
srand();
for (int i=; i<=; i++)
val[i] = (1ll*rand()*rand()*rand()+1ll*rand()*rand())^val[i-];
for (int T=read(); T; --T)
{
memset(head, -, sizeof head);
n = read(), m = read(), cnt = tot = edgeTot = ;
for (int i=; i<=n; i++) a[i] = read(), cnt = std::max(cnt, a[i])+;
for (int i=; i<n; i++) addedge(read(), read());
dfs(, );
for (int j=; j<=; j++)
for (int i=; i<=n; i++)
fat[i][j] = fat[fat[i][j-]][j-];
for (; m; --m)
{
int u = read(), v = read(), anc = lca(u, v);
query(, cnt, rt[u], rt[v], rt[anc], rt[fat[anc][]]);
}
}
return ;
}

END

【主席树上二分】bzoj5361: [Lydsy1805月赛]对称数的更多相关文章

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

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

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

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

  3. [Lydsy1805月赛] 对称数

    挺不错的一道数据结构题QWQ. 一开始发现这个题如果不看数据范围的话,妥妥的树上莫队啊23333,然鹅10组数据是不可能让你舒舒服服的树上莫队卡过的23333 于是想了想,这个题的模型就是,把u到v链 ...

  4. [Lydsy1805月赛]对称数 BZOJ5361

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

  5. BZOJ3932(主席树上二分+差分

    按时间作为主席树的版本,每个版本的主席树都是一个权值线段树. 差分消去时间影响 对于当前时间版本的主席树查询前K大即可. 树上二分时结束后切记判定l==r的状态(易错 l==r叶子节点可能存在多个值( ...

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

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

  7. BZOJ 1926: [Sdoi2010]粟粟的书架(主席树,二分答案)

    BZOJ 1926: [Sdoi2010]粟粟的书架(主席树,二分答案) 题意 : 给你一个长为\(R\)宽为\(C\)的矩阵,第\(i\)行\(j\)列的数为\(P_{i,j}\). 有\(m\)次 ...

  8. LOJ 2551 「JSOI2018」列队——主席树+二分

    题目:https://loj.ac/problem/2551 答案是排序后依次走到 K ~ K+r-l . 想维护一个区间排序后的结果,使得可以在上面二分.求和:二分可以知道贡献是正还是负. 于是想用 ...

  9. uoj#402. 【CTSC2018】混合果汁(主席树+二分)

    传送门 我们先把果汁按照美味度排序,枚举\(d\),那么肯定是贪心的选择美味程度不小于\(d\)的且最便宜的果汁 发现\(d\)可以二分,那么在主席树上二分就可以了 据说还有整体二分的大佬然而我并不会 ...

随机推荐

  1. jemeter+badboy录制脚本

    Jmeter 是一个非常流行的性能测试工具,虽然与LoadRunner相比有很多不足,比如:它结果分析能力没有LoadRunner详细:很它的优点也有很多: l       开源,他是一款开源的免费软 ...

  2. rake 任务参数传递问题解决

    原文 :  https://robots.thoughtbot.com/how-to-use-arguments-in-a-rake-task namespace :tweets do desc 'S ...

  3. SQL——行转列,列转行

    行转列,列转行是我们在开发过程中经常碰到的问题.行转列一般通过CASE WHEN 语句来实现,也可以通过 SQL SERVER 2005 新增的运算符PIVOT来实现.用传统的方法,比较好理解.层次清 ...

  4. Thinkpad T460声音问题

    ThinkPad T460,安装Windows 7 64位后,下载官网驱动各项正常,但声音在刚启动时正常,很快就变成无声状态,重新启动又会正常,如此反复,重新安装驱动依然存在. 后来在设备管理器中发现 ...

  5. poj 1155 输入输出问题

    http://acm.hust.edu.cn/vjudge/problem/16417 重做了一遍poj 1155 题目大意:给定一棵树,1为根结点表示电视台,有m个叶子节点表示客户,有n-m-1个中 ...

  6. 《Head First 设计模式》总结

    复合模式——模式的模式 MVC(模型-视图-控制器):是由数个设计模式结合起来的模式. 戴着模式的有色眼镜看MVC: 模型利用观察者模式让控制器和视图可以随最新的状态改变而更新. 模型对视图和控制器一 ...

  7. django orm 多对多自定义第三张表

    # -*- coding: utf-8 -*-# Generated by Django 1.11.11 on 2018-09-02 08:07from __future__ import unico ...

  8. 解析Excel文件 Apache POI框架使用

    本文整理了,使用Apache POI 框架解析.读取Excel文件,过程中,程序代码出现的一些问题,并解决 1..xls 和 .xlsx 我们知道Excel文档,在Windows下,分为Excel20 ...

  9. CentOS7.3下关于DHCP中继代理服务器的详细配置

    DHCP服务器只作用于局域网同一网段内,客户端是通过广播消息来获得DHCP服务器响应后才能得到IP地址的,但广播消息不能跨越子网,那么如何让客户端获取到DHCP服务器提供的IP地址呢?这就是DHCP中 ...

  10. 【2017-07-01】Linux应用开发工程师面试问题记录之二:关于结构体的大小及内存对齐问题

    Tencent后台服务器开发有一道题是计算一个结构体的sizeof的大小: struct strData { int m_Int; char m_Char; short m_Short; char m ...