[BZOJ5361]/[HDU6291]对称数

题目大意:

一个\(n(n\le2\times10^5)\)个结点的树,每个结点有一个权值\(a_i(a_i\le2\times10^5)\),\(m(m\le2\times10^5)\)次询问,每次询问\((u,v)\)路径上最小的出现偶数次的数。

思路:

对每个权值随机一个unsigned long long作为一个新的权值,树上主席树维护区间异或和。

询问时在主席树上二分即可。

源代码:

#include<cstdio>
#include<cctype>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<algorithm>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return x;
}
typedef unsigned long long uint64;
const int N=2e5+1,logN=40;
int a[N],v[N],anc[N][logN],dep[N],mex;
uint64 w[N],hsum[N];
std::vector<int> e[N];
inline void add_edge(const int &u,const int &v) {
e[u].push_back(v);
e[v].push_back(u);
}
inline int lg2(const float &x) {
return ((unsigned&)x>>23&255)-127;
}
class FotileTree {
#define mid ((b+e)>>1)
private:
struct Node {
uint64 val;
int left,right;
};
Node node[N*logN];
int sz,new_node(const int &p) {
node[++sz]=node[p];
return sz;
}
public:
void reset() {
sz=0;
}
int root[N];
void insert(int &p,const int &b,const int &e,const int &x) {
p=new_node(p);
node[p].val^=w[v[x]];
if(b==e) return;
if(x<=mid) insert(node[p].left,b,mid,x);
if(x>mid) insert(node[p].right,mid+1,e,x);
}
int query(const int &p,const int &q,const int &r,const int &s,const int &b,const int &e) const {
if((node[p].val^node[q].val^node[r].val^node[s].val)==(hsum[e]^hsum[b-1])) return mex;
if(b==e) return v[b];
const int tmp=query(node[p].left,node[q].left,node[r].left,node[s].left,b,mid);
if(tmp==mex) return query(node[p].right,node[q].right,node[r].right,node[s].right,mid+1,e);
return tmp;
}
#undef mid
};
FotileTree t;
void dfs(const int &x,const int &par) {
anc[x][0]=par;
dep[x]=dep[par]+1;
for(register int i=1;i<=lg2(dep[x]);i++) {
anc[x][i]=anc[anc[x][i-1]][i-1];
}
const int p=std::lower_bound(&v[1],&v[v[0]]+1,a[x])-v;
t.insert(t.root[x]=t.root[par],1,v[0],p);
for(unsigned i=0;i<e[x].size();i++) {
const int &y=e[x][i];
if(y==par) continue;
dfs(y,x);
}
}
inline int get_lca(int x,int y) {
if(dep[x]<dep[y]) std::swap(x,y);
for(register int i=lg2(dep[x]-dep[y]);i>=0;i--) {
if(dep[anc[x][i]]>=dep[y]) x=anc[x][i];
}
if(x==y) return x;
for(register int i=lg2(dep[x]);i>=0;i--) {
if(anc[x][i]!=anc[y][i]) {
x=anc[x][i];
y=anc[y][i];
}
}
return anc[x][0];
}
inline int query(const int &x,const int &y) {
const int lca=get_lca(x,y);
return std::min(t.query(t.root[x],t.root[y],t.root[lca],t.root[anc[lca][0]],1,v[0]),mex);
}
int main() {
srand(19961993);
for(register int T=getint();T;T--) {
memset(anc,0,sizeof anc);
const int n=getint(),m=getint();
for(register int i=1;i<=n;i++) {
v[i]=a[i]=getint();
while(w[a[i]]==0) {
w[a[i]]=(uint64)rand()*rand()*rand();
}
}
std::sort(&v[1],&v[n]+1);
v[0]=std::unique(&v[1],&v[n]+1)-v-1;
for(register int i=mex=1;i<=v[0];i++) {
hsum[i]=hsum[i-1]^w[v[i]];
if(v[i]==mex) mex++;
}
for(register int i=1;i<n;i++) {
add_edge(getint(),getint());
}
dfs(1,0);
for(register int i=0;i<m;i++) {
printf("%d\n",query(getint(),getint()));
}
t.reset();
for(register int i=1;i<=n;i++) {
e[i].clear();
}
}
return 0;
}

[BZOJ5361]/[HDU6291]对称数的更多相关文章

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

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

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

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

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

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

  4. [LeetCode] Strobogrammatic Number 对称数

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

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

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

  6. [LeetCode] 246. Strobogrammatic Number 对称数

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

  7. [LeetCode] 247. Strobogrammatic Number II 对称数II

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

  8. [LeetCode] 248. Strobogrammatic Number III 对称数III

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

  9. Python找对称数——纪念第一次自主编写代码

    2021-01-17 题目: [问题描述]已知10个四位数输出所有对称数及个数 n,例如1221.2332都是对称数[输入形式]10个四位数,以空格分隔开[输出形式]输入的四位数中的所有对称数,对称数 ...

随机推荐

  1. SDUT 3917

    UMR 现在手里有 n 张康纳的表情,最上面一张是玛吉呀巴库乃.现在 UMR 如果每次把最上面的 m 张牌移到最下面而不改变他们的顺序及朝向,那么至少经过多少次移动玛吉呀巴库乃才会又出现在最上面呢? ...

  2. 【leetcode 简单】第十题 实现strStr()

    实现 strStr() 函数. 给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始).如果不存在,则返 ...

  3. 自定义li项目符号

    使用background-image属性 先清除ul的默认list-style ul{ list-style:none } li{ background-image:url('./image/symb ...

  4. CSS Sprite笔记

    1. 什么是CSS Sprite 将一些碎小的图片拼接为一张大点的图片来使用,目的是为了减少浏览器的http请求次数以提高网页的加载速度.每次请求图片都需要跟服务器建立一次连接,并且浏览器的最大并发请 ...

  5. arch安装完成之后不能使用笔记本自带的无线网卡

    问题描述如下 我笔记本的wifi网卡识别不了,不知道为什么?? 使用ifconfig -a 只列出了有线网卡以及外接的无线网卡如下 enp4s0f1: flags=<UP,BROADCAST,M ...

  6. Mysql中的primary key 与auto_increment

    mysql> create table cc(id int auto_increment); ERROR (): Incorrect table definition; there can be ...

  7. python设计模式之单例模式(一)

    前言 单例模式是创建模式中比较常见和常用的模式,在程序执行的整个生命周期只存在一个实例对象. 系列文章 python设计模式之单例模式(一) python设计模式之常用创建模式总结(二) python ...

  8. [006] largest_common_substring

    [Description] Given two different strings, find the largest successive common substring. e.g. str1[] ...

  9. linux内核数据结构之链表【转】

    转自:http://www.cnblogs.com/Anker/p/3475643.html 1.前言 最近写代码需用到链表结构,正好公共库有关于链表的.第一眼看时,觉得有点新鲜,和我之前见到的链表结 ...

  10. python基础===map, reduce, filter的用法

    filter的用法: 这还是一个操作表list的内嵌函数'filter' 需要一个函数与一个list它用这个函数来决定哪个项应该被放入过滤结果队列中遍历list中的每一个值,输入到这个函数中如果这个函 ...