主席树 || 可持久化线段树 || 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的这条路径上的权值线段树 ----------------------- ...
随机推荐
- Visual Studio进行Web性能测试- Part III
Visual Studio进行Web性能测试- Part III 原文作者:Ambily.raj 对于一个多用户的应用程序,性能是非常重要的.性能不仅是执行的速度,它包括负载和并发方面.Visual ...
- 记一次免费让网站启用HTTPS的过程
写在前面 个人网站运行将近2个月了,期间根据酷壳的一篇教程如何免费的让网站启用HTTPS做了一次,中间遇到问题就放下了.昨天孙三苗问我网站地址说要添加友链,出于好奇想看他网站长什么样,顺道也加一下友链 ...
- 如何在VMware8虚拟机里安装Xp GHOST系统 解决不能启动Xp系统方法
好久没有装系统了.之前直接在硬盘中装,装个xp(c盘内).win7(d盘内).centos(虚拟机内)三系统同在一台笔记本电脑上.走了点弯路,这次记录下在虚拟机内装ghost xp. 安装步骤: 1. ...
- cpu使用过高的一次处理方法
1.top查看使用情况 2.查看mysql里的线程,观察是否有长期运行或阻塞的sql: show full processlist 原因找到,处理方法,添加索引,搞定
- 找不到指定的 VM 安装:类型 标准 VM,名称 jre7
问题背景是这样 原来使用的是jre7.0.55,后来为了安装使用 layabox IDE ,然后装了jdk_8u144 之后需要切换环境变量 之后java项目调试的时候重新设置了jdk,没问题. 直到 ...
- IntelliJIdea 2016.2 使用 tomcat 8.5 调试spring的web项目时,bean被实例化两次导致timer和thread被启动了两遍的问题的解决
今天新搭建了一个spring的web项目,项目启动时会启动一个线程,线程里定时执行任务,另外还启动了一个定时器,每秒钟统计系统吞吐量等业务性能数据.但是调试的时候惊奇的发现定时器和线程均被启动了两次. ...
- word,excel,ppt,txt转换为 PDF
/// <summary> /// 将word文档转换成PDF格式 /// </summary> /// <param name="sourcePath&quo ...
- 【Zookeeper】连接ZooKeeper的方式
使用客户端命令连接Zookeeper 连接Server 使用命令./zkCli.sh -server 127.0.0.1:2181 使用JAVA连接使用ZK POM添加引用 <dependenc ...
- const的位置问题
来源:牛客网 下列哪两个是等同的 int b; 1.const int *a = &b; 2.const * int a = &b; 3.const int* const a = &a ...
- Win10添加右键在此处打开命令行
通过添加注册表项,实现右击“在此处打开命令行功能” 注册表位置:HKEY_CLASSES_ROOT\Directory\Background\shell\ win10系统用标识右键菜单打开命令行的键, ...