bzoj2588 Spoj10628. count on a tree
题目描述
给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权。其中lastans是上一个询问的答案,初始为0,即第一个询问的u是明文。
输入输出格式
输入格式:
第一行两个整数N,M。
第二行有N个整数,其中第i个整数表示点i的权值。
后面N-1行每行两个整数(x,y),表示点x到点y有一条边。
最后M行每行两个整数(u,v,k),表示一组询问。
输出格式:
M行,表示每个询问的答案。
输入输出样例
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
2
8
9
105
7
说明
HINT:
N,M<=100000
暴力自重。。。
题解
其实就是个很简单的主席树,只要把在序列上的建树改成在树上建就可以了
虽然我也是今天看到这道题看完题解才知道怎么在树上建主席树
关于路径,可以在树上差分一下用$sum[l]+sum[r]-sum[lca]-sum[lca_fa]$
然后因为要求lca,所以在树剖dfs的时候顺便建一下主席树就好了
具体实现请参考代码
//minamoto
#include<bits/stdc++.h>
#define N 100005
#define M 2000005
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
int sum[M],L[M],R[M];
int a[N],b[N],rt[N];
int fa[N],sz[N],d[N],ver[N<<],Next[N<<],head[N],son[N],top[N];
int n,q,m,cnt=,tot=,ans=;
void update(int last,int &now,int l,int r,int x){
sum[now=++cnt]=sum[last]+;
if(l==r) return;
int mid=(l+r)>>;
if(x<=mid) R[now]=R[last],update(L[last],L[now],l,mid,x);
else L[now]=L[last],update(R[last],R[now],mid+,r,x);
}
inline void add(int u,int v){
ver[++tot]=v,Next[tot]=head[u],head[u]=tot;
ver[++tot]=u,Next[tot]=head[v],head[v]=tot;
}
void dfs(int u){
sz[u]=,d[u]=d[fa[u]]+;
update(rt[fa[u]],rt[u],,m,a[u]);
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(v==fa[u]) continue;
fa[v]=u,dfs(v);
sz[u]+=sz[v];
if(!son[u]||sz[v]>sz[son[u]]) son[u]=v;
}
}
void dfs(int u,int tp){
top[u]=tp;
if(!son[u]) return;
dfs(son[u],tp);
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(v==son[u]||v==fa[u]) continue;
dfs(v,v);
}
}
int LCA(int x,int y){
while(top[x]!=top[y])
d[top[x]]>=d[top[y]]?x=fa[top[x]]:y=fa[top[y]];
return d[x]>=d[y]?y:x;
}
int query(int ql,int qr,int lca,int lca_fa,int l,int r,int k){
if(l>=r) return l;
int x=sum[L[ql]]+sum[L[qr]]-sum[L[lca]]-sum[L[lca_fa]];
int mid=(l+r)>>;
if(x>=k) return query(L[ql],L[qr],L[lca],L[lca_fa],l,mid,k);
else return query(R[ql],R[qr],R[lca],R[lca_fa],mid+,r,k-x);
}
int main(){
//freopen("testdata.in","r",stdin);
n=read(),q=read();
for(int i=;i<=n;++i)
b[i]=a[i]=read();
sort(b+,b++n);
m=unique(b+,b++n)-b-;
for(int i=;i<=n;++i)
a[i]=lower_bound(b+,b++m,a[i])-b;
for(int i=;i<n;++i){
int u=read(),v=read();
add(u,v);
}
dfs(),dfs(,);
while(q--){
int x,y,z,lca;
x=read(),y=read(),z=read();
x^=ans,lca=LCA(x,y);
ans=b[query(rt[x],rt[y],rt[lca],rt[fa[lca]],,m,z)];
printf("%d\n",ans);
}
return ;
}
bzoj2588 Spoj10628. count on a tree的更多相关文章
- BZOJ2588 SPOJ10628 Count on a tree 【主席树】
BZOJ2588 Count on a tree 题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中l ...
- 【BZOJ2588】Count On a Tree(主席树)
[BZOJ2588]Count On a Tree(主席树) 题面 题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第 ...
- [bzoj2588][Spoj10628]Count on a tree_主席树
Count on a tree bzoj-2588 Spoj-10628 题目大意:给定一棵n个点的树,m次查询.查询路径上k小值. 注释:$1\le n,m\le 10^5$. 想法:好像更博顺序有 ...
- 【BZOJ-2588】Count on a tree 主席树 + 倍增
2588: Spoj 10628. Count on a tree Time Limit: 12 Sec Memory Limit: 128 MBSubmit: 3749 Solved: 873[ ...
- 【bzoj2588】Count on a tree
Portal -->bzoj2588 Solution 不行我一定要来挂这道题qwq很气愤qwq(其实还不是因为自己蠢..) 额首先说一下正解 如果这个问题放在序列上面的话..直接离散化一下然后 ...
- BZOJ2588:Count on a tree——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=2588 Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你 ...
- 主席树+LCA【p2633 (bzoj2588】 Count on a tree
Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始 ...
- 【bzoj2588】Count on a tree 主席树
这题给人开了个新思路. 原本构造一个序列的主席树,是这个位置用上个位置的信息来省空间,树上的主席树是继承父亲的信息来省空间. 此题若带修改怎么办? 若对某个点的权值做修改,则这个点的子树都会受影响,想 ...
- 【BZOJ2588】Count on a tree 题解(主席树+LCA)
前言:其实就是主席树板子啦……只不过变成了树上的查询 -------------------------- 题目链接 题目大意:求树上$u$到$v$路径第$k$大数. 查询静态区间第$k$大肯定是用主 ...
随机推荐
- bzoj2989&&4170数列——二进制分组+主席树
题意的转化挺巧妙的 可以联想到曼哈顿距离! 并且,所谓的修改还要查询历史版本,并且修改之间不动只算一次,不就是给平面上加一个点吗? 看成(x,a[x])的点 就是一个菱形区域 转切比雪夫距离,变成矩形 ...
- 猜数字小游戏,很naive......
这里用到了随机数生成器以及ctime #include <cstdio> #include <cstdlib> #include <ctime> #include ...
- [luoguU42591][小T的绝对值]
luoguU42592 20分思路 对给出的序列求出前缀和,然后\(n^2\)暴力枚举即可拿到第一档分 40分思路 对于数列中的数都相同的情况.只需要特判即可.只要特别注意全都是0的情况即可. 100 ...
- vue.js2.0开发中的几个技巧
最近用Vue.js开发了几个项目,Vue的双向数据绑定和组件化让我耳目一新,减少了很多底层重复的工作,和基于jQuey的前端开发不起来,基于Vue的开发给我一种酣畅淋漓的感觉. 下面给出我基于Vue. ...
- 求矩形面积(问题来自PythonTip)
描述: 已知矩形长a,宽b,输出其面积和周长,面积和周长以一个空格隔开. 例如:a = 3, b = 8 则输出:24 22 方法一: a=int(input('')) //input返回的是字符串类 ...
- pyglet -- 视频播放器 (简单实现,效果不是太好,切换资源会卡死)(三)
实现一个简单的视频播放器,效果不是很好.这里不多说,直接贴代码了. #-*- coding:gbk -*- import pyglet import os from pyglet.gl import ...
- UESTC - 1172 三句话题意
题目链接 记一个集合的gcd为该集合内所有数的最大公约数, 求一个给定集合的非空子集的gcd的k次方的期望~ Input 第一行有一个数t,表示数据组数 接下去每组数据两行,第一行两个数n,k(0 & ...
- VSCode 拓展插件推荐
想让VS code干活快起来,插件少不了,开始吧: 快捷键:Ctrl+Shift+X打开插件搜索安装即可 (安装的插件通常会保存在这个目录:C:\Users\你的系统登录用户如administrato ...
- DIV仿textarea文本域,contenteditable如何只能输入纯文本
对于支持HTML5浏览器有2种方法: 1. HTML5 <div contenteditable="plaintext-only"></div> 2. C ...
- C# http get与post请求方法
public class HttpTools { public static string GetRequest(string url) { HttpWebRequest request = (Htt ...