题面: 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. PhpStorm配置SVN的完整方法

    1.安装SVN时注意选择“command line client tools"默认是不安装的 2.设置系统环境变量 3.在PhpStorm上设置如下 4.然后通过VCS就可以上传导入你的工程 ...

  2. [Java] Windows/Linux路径不同时,统一war的最简办法

    作者: zyl910 一.缘由 在项目开发时,因为运行环境的不同,导致有时得分别为不同的环境,切换配置参数打不同war包.但手工切换配置文件的话,不仅费时费力,而且容易出错. 有些打包工具支持配置切换 ...

  3. SCF: 简单配置门面[转]

    原文:https://blog.csdn.net/koqizhao/article/details/82178100 Simple Configuration Facade :简单配置门面  是 代码 ...

  4. iOS CALayer 绘图模糊有锯齿的解决方案

    在CALayer中绘制图形会出现锯齿和模糊,同样绘图在UIView中就没有问题.经查资料发现不自动处理两倍像素的情况. 解决方案为:设置layer的contentsScale属性为[[UIScreen ...

  5. P Invoke struct结构

    一.获取Struct CHCNetSDK.NET_DVR_PTZPOS pos = new CameraTest.CHCNetSDK.NET_DVR_PTZPOS(); int size = Mars ...

  6. 一起来学习linux创建用户useradd命令

    linux创建用户useradd命令 原文地址:linux创建用户useradd命令 http://www.xfcodes.com/linuxcmd/user/24308.htm 一,adduser与 ...

  7. macOS 下 PHPStorm + Xdebug 调试 Docker 环境中的代码

    0x00 描述 宿主机是 mac mini,构建的项目在 docker 中,所以需要在 PHPStorm 上配置 Xdebug 进行远程代码调试. 0x01 环境 宿主机:macOS High Sie ...

  8. Spark基础

    1 读取本地文件 ./spark-shell scala> val textFile=sc.textFile("file:///home/hadoop/wordfile1.txt&qu ...

  9. Ubuntu环境使用apt命令下载管理包的优势

    操作系统:Ubuntu 18.04 LTS 一.概述 之前在Ubuntu下我一直坚持将软件下载包下载到指定文件夹下进行解压安装的习惯,在部门同事的建议下,我开始使用apt命令下载管理包. 由于网上已经 ...

  10. Flutter & Dart 安装在window系统

    一.系统环境 flutter最低要求 1,windows7 SP1 64位版本以上,我的系统就是windows 7 sp1 64bit 2,git for windows ,没有安装的需要到这里下载  ...