【题目大意】

给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权。其中lastans是上一个询问的答案,初始为0,即第一个询问的u是明文。
 
【思路】
这道题迷之好写,因为思路条理太清晰了!
我们每个点就是一棵线段树,维护它到根的每个数字的个数,但是这样会MLE所以自然而然地用主席树来维护。
u->v路径上每种的个数就等于sum[u]-sum[lca(u,v)]+sum[v]-sum[fa[lca(u,v)]]。
写起来特别爽。
然而我RE了一个上午。接着突然发现题意“(u,v)表示u到v有一条边)它居然是无向的??天真地以为有向u->v,调出了一开始的程序,默默地改掉,默默地AC...
还我两小时的人生!!!!
 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define lson l,m
#define rson m+1,r
using namespace std;
const int MAXN=+;
const int DEG=;
int w[MAXN];
vector<int> E[MAXN];
int d,hash[MAXN];
int T[MAXN],tot,sum[MAXN<<],L[MAXN<<],R[MAXN<<];
int anc[MAXN][DEG],dep[MAXN];
int n,m; /*Chairman Tree*/
int build(int l,int r)
{
int rt=++tot;
sum[rt]=;
if (l!=r)
{
int m=(l+r)>>;
L[rt]=build(lson);
R[rt]=build(rson);
}
return rt;
} int update(int pre,int l,int r,int x)
{
int rt=++tot;
L[rt]=L[pre],R[rt]=R[pre];
sum[rt]=sum[pre]+;
if (l!=r)
{
int m=(l+r)>>;
if (x<=m) L[rt]=update(L[pre],lson,x);
else R[rt]=update(R[pre],rson,x);
}
return rt;
} int query(int u,int v,int lca,int lcafa,int l,int r,int k)
{
if (l==r) return l;
int num=(sum[L[u]]-sum[L[lca]]+sum[L[v]]-sum[L[lcafa]]);
int m=(l+r)>>;
if (num>=k) return query(L[u],L[v],L[lca],L[lcafa],lson,k);
else return query(R[u],R[v],R[lca],R[lcafa],rson,k-num);
} /*LCA*/
void getanc()
{
for (int i=;i<DEG;i++)
for (int j=;j<=n;j++)
anc[j][i]=anc[anc[j][i-]][i-];
} int swim(int x,int H)
{
for (int i=;H>;i++)
{
if (H&) x=anc[x][i];
H>>=;
}
return x;
} int LCA(int u,int v)
{
if (dep[u]<dep[v]) swap(u,v);
u=swim(u,dep[u]-dep[v]);
if (u==v) return u;
for (int i=DEG-;i>=;i--)
{
if (anc[u][i]!=anc[v][i])
{
u=anc[u][i];
v=anc[v][i];
}
}
return anc[u][];
} /*main*/
void dfs(int u,int pa,int depth)
{
anc[u][]=pa;
dep[u]=depth;
int x=lower_bound(hash+,hash+d+,w[u])-hash;
T[u]=update(T[pa],,d,x);
for (int i=;i<E[u].size();i++)
if (E[u][i]!=pa) dfs(E[u][i],u,depth+);
} void init()
{
scanf("%d%d",&n,&m);
for (int i=;i<=n;i++) scanf("%d",&w[i]),hash[i]=w[i];
sort(hash+,hash+n+);
d=unique(hash+,hash+n+)-(hash+); for (int i=;i<n;i++)
{
int u,v;
scanf("%d%d",&u,&v);
E[u].push_back(v);
E[v].push_back(u);
} tot=;
T[]=build(,d);//对于根先建立主席树
} void solve()
{
getanc();
int preans=;
for (int i=;i<m;i++)
{
int u,v,k;
scanf("%d%d%d",&u,&v,&k);
u=u^preans;
int lca=LCA(u,v);
int ans=query(T[u],T[v],T[lca],T[anc[lca][]],,d,k);
printf("%d",hash[ans]);
if (i!=m-) printf("\n");
preans=hash[ans];
}
} int main()
{
init();
dfs(,,);
solve();
return ;
}

【树上主席树】BZOJ2588-Count on a tree的更多相关文章

  1. 洛谷P2633/bzoj2588 Count on a tree (主席树)

    洛谷P2633/bzoj2588 Count on a tree 题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K ...

  2. Count on a tree 树上主席树

    Count on a tree 树上主席树 给\(n\)个树,每个点有点权,每次询问\(u,v\)路径上第\(k\)小点权,强制在线 求解区间静态第\(k\)小即用主席树. 树上主席树类似于区间上主席 ...

  3. 【洛谷2633】Count on a tree(树上主席树)

    点此看题面 大致题意: 给你一棵树,每次问你两点之间第\(k\)小的点权,强制在线. 主席树 这种题目强制在线一般就是数据结构了. 而看到区间第\(k\)小,很容易就能想到主席树. 至少不会有人想到树 ...

  4. [bzoj2588][count on a tree] (主席树+lca)

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

  5. SPOJ COT Count on a tree(树上主席树 + LCA 求点第k小)题解

    题意:n个点的树,每个点有权值,问你u~v路径第k小的点的权值是? 思路: 树上主席树就是每个点建一棵权值线段树,具体看JQ博客,LCA用倍增logn求出,具体原理看这里 树上主席树我每个点的存的是点 ...

  6. p3302 [SDOI2013]森林(树上主席树+启发式合并)

    对着题目yy了一天加上看了一中午题解,终于搞明白了我太弱了 连边就是合并线段树,把小的集合合并到大的上,可以保证规模至少增加一半,复杂度可以是\(O(logn)\) 合并的时候暴力dfs修改倍增数组和 ...

  7. [CSP-S模拟测试]:e(树上主席树)

    题目传送门(内部题66) 输入格式 第一行,一个正整数$n$,一个自然数$q$,一个整数$type$.第二行,$n$个正整数,代表$a_i$.接下来$n-1$行,每行两个正整数$u$.$v$,代表树中 ...

  8. bzoj3123 [Sdoi2013]森林 树上主席树+启发式合并

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=3123 题解 如果是静态的查询操作,那么就是直接树上主席树的板子. 但是我们现在有了一个连接两棵 ...

  9. BZOJ2588 Count on a tree 【树上主席树】

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MB Submit: 7577  Solved: 185 ...

随机推荐

  1. 2017ACM暑期多校联合训练 - Team 2 1001 HDU 6045 Is Derek lying? (模拟)

    题目链接 Problem Description Derek and Alfia are good friends.Derek is Chinese,and Alfia is Austrian.Thi ...

  2. HDU 1214 圆桌会议 (找规律)

    题目链接 Problem Description HDU ACM集训队的队员在暑假集训时经常要讨论自己在做题中遇到的问题.每当面临自己解决不了的问题时,他们就会围坐在一张圆形的桌子旁进行交流,经过大家 ...

  3. xshell5破解版下载

    http://www.pc6.com/softview/SoftView_507840.html

  4. CentOS 6.5 安装 MongoDB

    1. 配置 yum 新建 /etc/yum.repos.d/mongodb-org-3.4.repo 文件,使用以下配置:(适用于 MongoDB 3.0 以后版本) [mongodb-org-3.4 ...

  5. 【swupdate文档 五】从可信的来源更新镜像

    从可信的来源更新镜像 现在越来越重要的是,设备不仅要能安全地进行更新操作, 而且要能够验证发送的图像是否来自一个已知的源, 并且没有嵌入恶意软件. 为了实现这个目标,SWUpdate必须验证传入的镜像 ...

  6. python基础===对字符串进行左右中对齐

    例如,有一个字典如下: >>> dic = { "name": "botoo", "url": "http:// ...

  7. spring mvc 自定义编辑器

    起始知识: Java标准的PropertyEditor的核心功能是将一个字符串转换为一个Java对象,以便根据界面的输入或配置文件中的配置字符串构造出一个JVM内部的java对象. 如何注册自定义的属 ...

  8. Linux shell中运行命令后加上字符“&”的作用(转)

    原文链接为:http://blog.sina.com.cn/s/blog_963453200102uya7.html & 放在启动参数后面表示设置此进程为后台进程 默认情况下,进程是前台进程, ...

  9. Linux 用户篇——用户管理命令之id、whoami、su、chage

    一.浅谈id.whoami.su.chage 本篇是续写上一篇<Linux 用户篇——用户管理命令之useradd.passwd.userdel.usermod>. (1)id命令 命令格 ...

  10. NIO-4pipe

    import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.Pipe; import org.ju ...