主席树 || 可持久化线段树 || 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))-ans(father[LCA(X,Y)])
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=+,maxm=maxn,maxlog=;
int lastans=,num_edge=,edge_head[maxn],N,M,F[maxn][maxlog+];
int Dep[maxn],num_treenode=,root[maxn],lsh_cnt=,cor[maxn],U,V,K,X,Y;
inline int rd(){
int x=,f=;char c=getchar();
while(c<''||c>''){if(c=='-')f=-; c=getchar();}
while(c>=''&&c<=''){x=x*+c-''; c=getchar();}
return f*x;
}
struct Edge{int to,nx;}edge[maxn<<];
inline void Add_edge(int from,int to){
edge[++num_edge].nx=edge_head[from];
edge[num_edge].to=to;
edge_head[from]=num_edge;
return;
}
struct Tree{int cnt,l,r,ls,rs;}t[(maxn<<)+maxn*maxlog];
inline void Build(int x,int l,int r){
t[x].l=l;t[x].r=r;int mid=(l+r)>>;
if(l==r)return;
Build(t[x].ls=++num_treenode,l,mid);
Build(t[x].rs=++num_treenode,mid+,r);
return;
}
inline void Update(int u,int x,int s){
int l=t[u].l,r=t[u].r,mid=(l+r)>>;
t[x].l=l;t[x].r=r;
if(l==r&&l==s){t[x].cnt=t[u].cnt+; return;}
if(s<=mid){t[x].rs=t[u].rs; Update(t[u].ls,t[x].ls=++num_treenode,s);}
else{t[x].ls=t[u].ls; Update(t[u].rs,t[x].rs=++num_treenode,s);}
t[x].cnt=t[t[x].ls].cnt+t[t[x].rs].cnt;
return;
}
struct A_{int yn,hn,id;}A[maxn];
inline void Dfs(int x,int fa){
Dep[x]=Dep[fa]+;
F[x][]=fa;
for(int i=;i<=maxlog;i++)
F[x][i]=F[F[x][i-]][i-];
Update(root[fa],root[x]=++num_treenode,A[x].hn);
for(int i=edge_head[x];i;i=edge[i].nx){
int y=edge[i].to;
if(y==fa)continue;
Dfs(y,x);
}
return;
}
inline int LCA(int x,int y){
if(Dep[x]<Dep[y])swap(x,y);
for(int i=maxlog;i>=;i--){
if(Dep[F[x][i]]>=Dep[y])x=F[x][i];
if(x==y)return x;
}
for(int i=maxlog;i>=;i--){
if(F[x][i]!=F[y][i]){
x=F[x][i];y=F[y][i];
}
}
return F[x][];
}
inline bool cmp(const A_&a,const A_&b){return a.yn<b.yn;}
inline bool cmp2(const A_&a,const A_&b){return a.id<b.id;}
inline int Query(int u,int v,int z,int w,int k){
int l=t[u].l,r=t[u].r;
if(l==r)return l;
int a=t[t[u].ls].cnt+t[t[v].ls].cnt-t[t[z].ls].cnt-t[t[w].ls].cnt;
if(a>=k)return Query(t[u].ls,t[v].ls,t[z].ls,t[w].ls,k);
else return Query(t[u].rs,t[v].rs,t[z].rs,t[w].rs,k-a);
}
int main(){
N=rd();M=rd();
for(int i=;i<=N;i++)A[i].yn=rd(),A[i].id=i;
sort(A+,A+N+,cmp);
cor[A[].hn=++lsh_cnt]=A[].yn;
for(int i=;i<=N;i++)
if(A[i-].yn!=A[i].yn)
cor[A[i].hn=++lsh_cnt]=A[i].yn;
else A[i].hn=lsh_cnt;
sort(A+,A+N+,cmp2);
for(int i=;i<N;i++){
X=rd();Y=rd();
Add_edge(X,Y);Add_edge(Y,X);
}
Build(root[]=++num_treenode,,lsh_cnt+);
Dfs(,);
while(M--){
U=rd();V=rd();K=rd();
U^=lastans;
int lca=LCA(U,V);
lastans=Query(root[U],root[V],root[lca],root[F[lca][]],K);
lastans=cor[lastans];
if(M==)printf("%d",lastans);else printf("%d\n",lastans);
}
return ;
}
By:AlenaNuna
主席树 || 可持久化线段树 || LCA || BZOJ 2588: Spoj 10628. Count on a tree || Luogu P2633 Count on a tree的更多相关文章
- 主席树||可持久化线段树+离散化 || 莫队+分块 ||BZOJ 3585: mex || Luogu P4137 Rmq Problem / mex
题面:Rmq Problem / mex 题解: 先离散化,然后插一堆空白,大体就是如果(对于以a.data<b.data排序后的A)A[i-1].data+1!=A[i].data,则插一个空 ...
- [BZOJ 4771]七彩树(可持久化线段树+树上差分)
[BZOJ 4771]七彩树(可持久化线段树+树上差分) 题面 给定一棵n个点的有根树,编号依次为1到n,其中1号点是根节点.每个节点都被染上了某一种颜色,其中第i个节点的颜色为c[i].如果c[i] ...
- BZOJ 2588: Spoj 10628. Count on a tree-可持久化线段树+LCA(点权)(树上的操作) 无语(为什么我的LCA的板子不对)
2588: Spoj 10628. Count on a tree Time Limit: 12 Sec Memory Limit: 128 MBSubmit: 9280 Solved: 2421 ...
- BZOJ - 2588 Spoj 10628. Count on a tree (可持久化线段树+LCA/树链剖分)
题目链接 第一种方法,dfs序上建可持久化线段树,然后询问的时候把两点之间的所有树链扒出来做差. #include<bits/stdc++.h> using namespace std; ...
- 主席树[可持久化线段树](hdu 2665 Kth number、SP 10628 Count on a tree、ZOJ 2112 Dynamic Rankings、codeforces 813E Army Creation、codeforces960F:Pathwalks )
在今天三黑(恶意评分刷上去的那种)两紫的智推中,突然出现了P3834 [模板]可持久化线段树 1(主席树)就突然有了不详的预感2333 果然...然后我gg了!被大佬虐了! hdu 2665 Kth ...
- BZOJ.4771.七彩树(可持久化线段树)
BZOJ 考虑没有深度限制,对整棵子树询问怎么做. 对于同种颜色中DFS序相邻的两个点\(u,v\),在\(dfn[u],dfn[v]\)处分别\(+1\),\(dfn[LCA(u,v)]\)处\(- ...
- BZOJ4771七彩树——可持久化线段树+set+树链的并+LCA
给定一棵n个点的有根树,编号依次为1到n,其中1号点是根节点.每个节点都被染上了某一种颜色,其中第i个节 点的颜色为c[i].如果c[i]=c[j],那么我们认为点i和点j拥有相同的颜色.定义dept ...
- 归并树 划分树 可持久化线段树(主席树) 入门题 hdu 2665
如果题目给出1e5的数据范围,,以前只会用n*log(n)的方法去想 今天学了一下两三种n*n*log(n)的数据结构 他们就是大名鼎鼎的 归并树 划分树 主席树,,,, 首先来说两个问题,,区间第k ...
- BZOJ 2588: Spoj 10628. Count on a tree( LCA + 主席树 )
Orz..跑得还挺快的#10 自从会树链剖分后LCA就没写过倍增了... 这道题用可持久化线段树..点x的线段树表示ROOT到x的这条路径上的权值线段树 ----------------------- ...
随机推荐
- 【Inno Setup】添加许可协议,并默认选中我同意按钮
[Setup] ; xkfile.txt文件不能为空 LicenseFile=C:\Documents and Settings\Administrator\桌面\smqh\xkfile.txt ...
- matplotlib 与 seaborn 中出现中文乱码的解决方法
Linux.Mac osx 系统中,出现 matplotlib 或 seaborn 绘图中有中文乱码的情形,可以考虑使用以下方式处理: 到 anaconda 的 matplotlib 中查看是否有 ...
- Delphi 如何操作Excel
摘自:http://wenjieshiyu.blog.163.com/blog/static/10739413201072033115869/ 个人收藏:Delphi 控制Excel(一) 使用动态 ...
- 【Git】git pull和git pull --rebase的使用
git pull = git fetch + git mergegit pull --rebase = git fetch + git rebase 现在来看看git merge和git rebase ...
- count(*)、count(1)和count(列名)的区别
count(*).count(1)和count(列名)的区别 1.执行效果上: l count(*)包括了所有的列,相当于行数,在统计结果的时候,不会忽略列值为NULL l count(1)包 ...
- getCanonicalFile与getAbsoluteFile区别
package test; import java.io.File; import java.io.IOException; public class TestFilePath { public st ...
- springboot项目使用拦截器修改/添加前端传输到后台header和cookie参数
本质上来讲,request请求当中的参数是无法更改的,也不能添加或者删除. 但在后台程序中,一般对request的参数的操作,都是通过request的getParameter.getParameter ...
- 使用Docker快速创建.Net Core2.0 Nginx负载均衡节点
本文版权归博客园和作者吴双本人共同所有 转载和爬虫请注明原文地址 www.cnblogs.com/tdws 一.Self-Host Kestrel 1. 在vs2017中新建dotnet core2. ...
- babel配置项目目录支持转换es6语法,引入非项目目录js后,引入Js转换无效
我遇到了一个问题,我在已经配置babel的项目中通过require引入了一个项目目录外层的另一个js文件,前期是可以成功转换并打包的,但是到了后期就不行了,报错: 这个报错的意思是,引入的js文件中有 ...
- mysql按位的索引判断位的值
DELIMITER $$ DROP FUNCTION IF EXISTS `value_of_bit_index`$$/*计算数字的某个位的值*/CREATE FUNCTION `value_of_b ...