Description

给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权。其中lastans是上一个询问的答案,初始为0,即第一个询问的u是明文。
 

Input

第一行两个整数N,M。
第二行有N个整数,其中第i个整数表示点i的权值。
后面N-1行每行两个整数(x,y),表示点x到点y有一条边。
最后M行每行两个整数(u,v,k),表示一组询问。
 

Output

M行,表示每个询问的答案。最后一个询问不输出换行符

Sample Input

8 5
105 2 9 3 8 5 7 7
1 2
1 3
1 4
3 5
3 6
3 7
4 8
2 5 1
0 5 2
10 5 3
11 5 4
110 8 2

Sample Output

2
8
9
105
7

HINT

HINT:
N,M<=100000
暴力自重。。。
 
思路:
强制在线,lca + 主席树
 
实现代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define mid int m = (l + r) >> 1
const int M = 2e5 + ;
int p[M][],dep[M],head[M],sum[M*],ls[M*],rs[M*],root[M*];
int cnt1,n,idx,cnt,f[M]; struct node {
int to,next;
}e[M]; void add(int u,int v){
e[++cnt1].to=v;e[cnt1].next=head[u];head[u]=cnt1;
e[++cnt1].to=u;e[cnt1].next=head[v];head[v]=cnt1;
} int lca(int a,int b){
if(dep[a] > dep[b]) swap(a,b);
int h = dep[b] - dep[a];
for(int i = ;(<<i)<=h;i++){
if((<<i)&h) b = p[b][i];
} if(a!=b){
for(int i = ;i >= ;i --){
if(p[a][i]!=p[b][i]){
a = p[a][i]; b = p[b][i];
}
}
a = p[a][];
}
return a;
} void build(int l,int r,int &rt){
rt = ++idx;
sum[rt] = ;
if(l == r) return;
mid;
build(l,m,ls[rt]);
build(m+,r,rs[rt]);
} void update(int p,int l,int r,int old,int &rt){
rt = ++idx;
ls[rt] = ls[old]; rs[rt] = rs[old]; sum[rt] = sum[old] + ;
if(l == r) return ;
mid;
if(p <= m) update(p,l,m,ls[old],ls[rt]);
else update(p,m+,r,rs[old],rs[rt]);
} int query(int a,int b,int lc,int cl,int l,int r,int k){
if(l == r) return l;
mid;
int cnt = sum[ls[a]] + sum[ls[b]] - sum[ls[lc]] - sum[ls[cl]];
if(k <= cnt)
return query(ls[a],ls[b],ls[lc],ls[cl],l,m,k);
else
return query(rs[a],rs[b],rs[lc],rs[cl],m+,r,k-cnt);
}
int a[M],b[M]; void dfs(int u,int fa){
f[u] = fa;
update(a[u],,cnt,root[fa],root[u]);
for(int i = head[u];i;i = e[i].next){
int v = e[i].to;
if(v == fa) continue;
p[v][] = u;
dep[v] = dep[u] + ;
dfs(v,u);
}
} void init()
{
cnt1 = ; idx = ;
memset(head,,sizeof(head));
memset(dep,,sizeof(dep));
memset(p,,sizeof(p));
memset(f,,sizeof(f));
dep[] = ;
} int main()
{
int m;
while(scanf("%d%d",&n,&m)!=EOF){
init();
for(int i = ; i <= n;i ++){
scanf("%d",&a[i]);
b[i] = a[i];
}
int l,r,c;
sort(b+,b+n+);
cnt = unique(b+,b++n)-b-;
for(int i = ;i <= n;i ++)
a[i] = lower_bound(b+,b+cnt+,a[i]) - b;
for(int i = ;i <= n-;i ++){
scanf("%d%d",&l,&r);
add(l,r);
}
build(,cnt,root[]);
dfs(,);
for(int j = ;(<<j)<=n;j++)
for(int i = ;i <= n;i++)
p[i][j] = p[p[i][j-]][j-];
int num = ;
for(int i = ;i <= m;i ++){
scanf("%d%d%d",&l,&r,&c);
l = l^num;
int lc = lca(l,r);
int id = query(root[l],root[r],root[lc],root[f[lc]],,cnt,c);
num = b[id];
printf("%d\n",b[id]);
}
}
return ;
}

bzoj 2588 : Spoj 10628. Count on a tree的更多相关文章

  1. BZOJ 2588: Spoj 10628. Count on a tree [树上主席树]

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MBSubmit: 5217  Solved: 1233 ...

  2. BZOJ 2588: Spoj 10628. Count on a tree 树上跑主席树

    2588: Spoj 10628. Count on a tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/J ...

  3. Bzoj 2588: Spoj 10628. Count on a tree 主席树,离散化,可持久,倍增LCA

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2588 2588: Spoj 10628. Count on a tree Time Limit ...

  4. BZOJ 2588: Spoj 10628. Count on a tree( LCA + 主席树 )

    Orz..跑得还挺快的#10 自从会树链剖分后LCA就没写过倍增了... 这道题用可持久化线段树..点x的线段树表示ROOT到x的这条路径上的权值线段树 ----------------------- ...

  5. Bzoj 2588 Spoj 10628. Count on a tree(树链剖分LCA+主席树)

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec Memory Limit: 128 MB Description 给定一棵N个节点的树,每个点 ...

  6. bzoj 2588 Spoj 10628. Count on a tree (可持久化线段树)

    Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MBSubmit: 7669  Solved: 1894[Submi ...

  7. 主席树 || 可持久化线段树 || LCA || BZOJ 2588: Spoj 10628. Count on a tree || Luogu P2633 Count on a tree

    题面: Count on a tree 题解: 主席树维护每个节点到根节点的权值出现次数,大体和主席树典型做法差不多,对于询问(X,Y),答案要计算ans(X)+ans(Y)-ans(LCA(X,Y) ...

  8. BZOJ 2588: Spoj 10628. Count on a tree 主席树+lca

    分析:树上第k小,然后我想说的是主席树并不局限于线性表 详细分析请看http://www.cnblogs.com/rausen/p/4006116.html,讲的很好, 然后因为这个熟悉了主席树,真是 ...

  9. ●BZOJ 2588 Spoj 10628. Count on a tree

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2588 题解: 主席树,在线,(求LCA)感觉主席树真的好厉害...在原树上建主席树.即对于原 ...

  10. 洛谷 2633 BZOJ 2588 Spoj 10628. Count on a tree

    [题解] 蜜汁强制在线... 每个点开一个从它到根的可持久化权值线段树.查询的时候利用差分的思想在树上左右横跳就好了. #include<cstdio> #include<algor ...

随机推荐

  1. Final Destination II -- 矩阵快速幂模板题

    求f[n]=f[n-1]+f[n-2]+f[n-3] 我们知道 f[n] f[n-1] f[n-2]         f[n-1]  f[n-2]  f[n-3]         1    1    ...

  2. rbac权限+中间件

    1.权限组件rbac 1.什么是权限 1 项目与应用 2 什么是权限? 一个包含正则表达式url就是一个权限 who what how ---------->True or Flase 2.版本 ...

  3. 课程存储校对:程序设计思想、源程序代码、运行结果截图,以及开发过程中的项目计划日志、时间记录日志、缺陷记录日志(PSP0级记录)。

    1.程序设计思想 ⑴将JDBC驱动jar包导入到WEB-INF的lib文件夹下 ⑵建立数据库,在数据库中建表,分别将课程名称.任课教师及上课地点录入到列中 ⑶首先写出加载驱动.关闭资源的工具类和异常处 ...

  4. 解决ConnectionRefusedError: [WinError 10061] 由于目标计算机积极拒绝,无法连接。

    解决办法:

  5. Linux下面将windows写的脚本转换成 Linux 格式的文件

    1.接着上一篇blog 发现有一个问题 vim 打开文件 发现最下面有一行信息: 2. 里面有一些 不一样的地方. linux里面没法执行 ,如果想执行的话 可以输入命令 :set fileforma ...

  6. HDU 2459 Maximum repetition substring

    题目:Maximum repetition substring 链接:http://acm.hdu.edu.cn/showproblem.php?pid=2459 题意:给你一个字符串,求连续重复出现 ...

  7. 【学亮IT手记】PL/SQL游标编程

    游标提供了一种从表中检索数据并进行操作的灵活手段,主要用在服务器上,处理由客户端发送给服务器端的sql语句,或者是批处理.存储过程.触发器中的数据处理请求. 显式游标 是由用户声明和操作的一种游标,通 ...

  8. java中的a++与++a的区别

    ++a:如果++在前就会先把a+1. a++:如果++在后就会先a然后在执行++的操作.代码: int a = 1; System.out.pritln(++a); //输出2 int s = 1; ...

  9. Java内存泄漏分析

    https://www.javatang.com/archives/2017/11/08/11582145.html?tdsourcetag=s_pcqq_aiomsg

  10. python之路--subprocess,粘包现象与解决办法,缓冲区

    一. subprocess 的简单用法 import subprocess sub_obj = subprocess.Popen( 'dir', #系统指令 shell=True, #固定方法 std ...