题面: 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的更多相关文章

  1. 主席树||可持久化线段树+离散化 || 莫队+分块 ||BZOJ 3585: mex || Luogu P4137 Rmq Problem / mex

    题面:Rmq Problem / mex 题解: 先离散化,然后插一堆空白,大体就是如果(对于以a.data<b.data排序后的A)A[i-1].data+1!=A[i].data,则插一个空 ...

  2. [BZOJ 4771]七彩树(可持久化线段树+树上差分)

    [BZOJ 4771]七彩树(可持久化线段树+树上差分) 题面 给定一棵n个点的有根树,编号依次为1到n,其中1号点是根节点.每个节点都被染上了某一种颜色,其中第i个节点的颜色为c[i].如果c[i] ...

  3. 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 ...

  4. BZOJ - 2588 Spoj 10628. Count on a tree (可持久化线段树+LCA/树链剖分)

    题目链接 第一种方法,dfs序上建可持久化线段树,然后询问的时候把两点之间的所有树链扒出来做差. #include<bits/stdc++.h> using namespace std; ...

  5. 主席树[可持久化线段树](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 ...

  6. BZOJ.4771.七彩树(可持久化线段树)

    BZOJ 考虑没有深度限制,对整棵子树询问怎么做. 对于同种颜色中DFS序相邻的两个点\(u,v\),在\(dfn[u],dfn[v]\)处分别\(+1\),\(dfn[LCA(u,v)]\)处\(- ...

  7. BZOJ4771七彩树——可持久化线段树+set+树链的并+LCA

    给定一棵n个点的有根树,编号依次为1到n,其中1号点是根节点.每个节点都被染上了某一种颜色,其中第i个节 点的颜色为c[i].如果c[i]=c[j],那么我们认为点i和点j拥有相同的颜色.定义dept ...

  8. 归并树 划分树 可持久化线段树(主席树) 入门题 hdu 2665

    如果题目给出1e5的数据范围,,以前只会用n*log(n)的方法去想 今天学了一下两三种n*n*log(n)的数据结构 他们就是大名鼎鼎的 归并树 划分树 主席树,,,, 首先来说两个问题,,区间第k ...

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

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

随机推荐

  1. 我的博客即将搬运同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=i5j7gwrxj9x5

    我的博客即将搬运同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=i5j7gwrxj9x5

  2. 设计模式之二十一:中介者模式(Mediator)

    中介者模式:定义了一个对象.用来封装一系列对象的交互.中介者模式通过使对象之间不必显式引用减少了对象之间的耦合,而且同意你独立改变它们之间的交互. 中介者模式就是将对象之间的交互封装在了一个独立的对象 ...

  3. 在 java 开发接口中需要注意的问题

    1 在开发过程中免不了对接上游或下游,有合作就要保证入参.出参的准确性.一个接口一般只能处理有限情况下的情况,因此在逻辑处理前要对入参进行校验. 2 在自己的逻辑处理过程中,要时刻持有怀疑的态度.假设 ...

  4. docker的/var/lib/docker/overlay文件夹突然占满了硬盘

    场景描述 事情是这样的,前两天客户的服务器突然断电了,导致用docker部署的服务也挂了.昨天去现场,重启了docker,同时准备更新一下服务.结果发现有一台节点硬盘满了- 还是觉得有些奇怪的,毕竟d ...

  5. idea maven 集成多模块 module

    首先第一步创建 顶级项目  也就是父项目 在创面那部中 不管你勾不勾 create from 那个选项 都无所谓,最终创建的项目要全删的 ,只保留pom.xml 父项目结构 接下来 创建子项目  也是 ...

  6. Java根据子节点递归父节点

    先上数据库结构图和树形图: 项目中的一个需求是获取一个商品所属的二级分类名称. 思路分析,首先,我们是可以拿到当前商品所属的子分类的,比如说我买的是一个iPhone SE,对应的分类名称是 iPhon ...

  7. 在Linux添加定时任务删除5天前的日志文件

    利用shell脚本自动清理,脚本如下 1.删除文件命令: find 对应目录 -mtime +天数 -name "文件名" -exec rm -rf {} \; 实例命令: fin ...

  8. 关于Unity中物体分别在本地和世界坐标系对应方向的移动

    方向 Vector3可以定义以世界坐标轴为参考的三维矢量,Vector3.forward,Vector3.up,Vector3.right方别对应物体世界坐标系的Z,Y,X轴方向的单位向量,或者叫三维 ...

  9. Mysql 5.7 安装 解压缩版 忘记密码

    [参考]Mysql 命令大全 [参考]MySQL 5.7.19 忘记密码 重置密码 配置文件my.ini示例 服务启动后停止 log配置 [参考]MySQL5.7.19 服务挂掉 自动关闭 mysql ...

  10. 复制id_rsa命令

    pbcopy < ~/.ssh/id_rsa.pub https://aliasan-conf.taijiankong.cn/duotai/2T7b253i8.pac