主席树 || 可持久化线段树 || 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的这条路径上的权值线段树 ----------------------- ...
随机推荐
- Replication基础(六) 复制中的三个线程(IO/SQL/Dump)
Reference: https://blog.csdn.net/sun_ashe/article/details/82181811?utm_source=blogxgwz1 简介在MySQL复制技 ...
- eclipse is missing required source folder src/test/java
原因:maven的bug,不兼容eclipse 解决方法:右击工程,选择run-->maven-->build重新构建工程,就解决了.
- [C++]Qt程式异常崩溃处理技巧(Win)
文章转载来自 http://www.cnblogs.com/lcchuguo/p/5177715.html 作者 lcchuguo https://blog.csdn.net/baid ...
- HashMap中capacity、loadFactor、threshold、size等概念的解释<转>
最近在看HashMap的源码,有很多概念都很模糊,今天写了一个测试例子,加深对这几个概念的理解,并演示了扩容及树化的过程(见下篇博文:). 注:本文基于JDK 1.8 HashMap的结构 约定 约 ...
- Linux常用的基础组件
Linux服务器(新机器) yum install gcc gcc-c++ glibc-devel make ncurses-devel openssl-devel autoconf git yum ...
- Codeforces Round #313 (Div. 2) C. Gerald's Hexagon(补大三角形)
C. Gerald's Hexagon time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- android6.0 Activity(四) Surface创建
原文:http://blog.csdn.net/luoshengyang/article/details/8303098.原文代码比較老了,可是核心不变.在原文基础上改动了一些代码,以及增加自己 ...
- golang加油!
- android studio设置imageview显示图片
拖动imageview 选择图片 .png 代码引用: private Imageview pay; pay = (ImageView)findViewById(R.id.imageView2); p ...
- 更改了react-redux 官方网站的todolist结构
最近在学习胡子大哈的react小书,内容讲的由浅入深,很值得react,react-redux小白一读. 废话不多说直接上地址:http://huziketang.mangojuice.top/boo ...