bzoj 2588 Count on a tree
Description
Input
Output
M行,表示每个询问的答案。最后一个询问不输出换行符
Sample Input
105 2 9 3 8 5 7 7
1 2
1 3
1 4
3 5
3 6
3 7
4 8
2 5 1
0 5 2
10 5 3
11 5 4
110 8 2
Sample Output
8
9
105
7
HINT
Source
树上的主席树,本来应该自已YY一下的但是没有想出来。。。尴尬。。。
其实还是很简单的。。。
每个节点以其父亲节点为历史版本建主席树,在dfs的时候insert;
那么每个点的线段树相当于是维护了从根节点到该节点路径上的点。。。
对于树上两点l,r路径上的第k大,那么要找出l,r的LCA,由于这个LCA也是需要被考虑的,所以还要求LCA的爸爸;
所以每次相当于是 s[ls[l]]+s[ls[r]]-s[ls[lca]]-s[ls[fa[lca]];
这个东西把图画出来,其实就是一个树上的前缀和思想。。。
附上代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=;
int gi()
{
int x=,flag=;
char ch=getchar();
while(ch<''||ch>''){if(ch=='-') flag=-;ch=getchar();}
while(ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
return x*flag;
}
int hash[N],num[N],v[N],s[N*],sz,root[N],ls[N*],rs[N*];
int dfn[N],head[N*],nxt[N*],to[N*],son[N],dep[N],size[N],fa[N],top[N];
int id[N],tt,cnt,tot,n,m,last;
int find(int x)
{
int l=,r=tot;
while(l<=r)
{
int mid=(l+r)>>;
if(hash[mid]<x) l=mid+;
else r=mid-;
}
return l;
}
void insert(int l,int r,int x,int &y,int k)
{
y=++sz;
s[y]=s[x]+;ls[y]=ls[x],rs[y]=rs[x];
if(l==r) return;
int mid=(l+r)>>;
if(k<=mid) insert(l,mid,ls[x],ls[y],k);
else insert(mid+,r,rs[x],rs[y],k);
}
int query(int l,int r,int a,int b,int c,int d,int k)
{
if(l==r) return hash[l];
int mid=(l+r)>>;
if(s[ls[a]]+s[ls[b]]-s[ls[c]]-s[ls[d]]>=k)
return query(l,mid,ls[a],ls[b],ls[c],ls[d],k);
else return query(mid+,r,rs[a],rs[b],rs[c],rs[d],k-(s[ls[a]]+s[ls[b]]-s[ls[c]]-s[ls[d]]));
}
void dfs1(int x,int f)
{
dep[x]=dep[f]+;size[x]=;
insert(,tot,root[f],root[x],find(v[x]));
for(int i=head[x]; i; i=nxt[i])
{
int y=to[i];
if(y!=f)
{
dfs1(y,x);
fa[y]=x;size[x]+=size[y];
if(size[y]>size[son[x]]) son[x]=y;
}
}
}
void dfs2(int x,int f)
{
dfn[x]=++tt,top[x]=f;
if(son[x]) dfs2(son[x],f);
for(int i=head[x]; i; i=nxt[i])
{
int y=to[i];
if(y!=fa[x]&&y!=son[x]) dfs2(y,y);
}
}
int lca(int x,int y)
{
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
x=fa[top[x]];
}
if(dep[x]<dep[y]) swap(x,y);
return y;
}
void lnk(int x,int y)
{
to[++cnt]=y,nxt[cnt]=head[x],head[x]=cnt;
to[++cnt]=x,nxt[cnt]=head[y],head[y]=cnt;
}
int main()
{
n=gi(),m=gi();
for(int i=; i<=n; i++) v[i]=gi(),num[i]=v[i];
sort(num+,num++n);
hash[++tot]=num[];
for(int i=; i<=n; i++)
if(num[i]!=num[i-])
hash[++tot]=num[i];
int x,y,k;
for(int i=; i<n; i++) x=gi(),y=gi(),lnk(x,y);
dfs1(,);dfs2(,);
for(int i=; i<=m; i++)
{
x=gi();y=gi();k=gi();x^=last;
int a=root[x],b=root[y],c=root[lca(x,y)],d=root[fa[lca(x,y)]];
last=query(,tot,a,b,c,d,k);
printf("%d",last);if(i!=m) printf("\n");
}
}
bzoj 2588 Count on a tree的更多相关文章
- bzoj 2588 Count on a tree 解题报告
Count on a tree 题目描述 给定一棵\(N\)个节点的树,每个点有一个权值,对于\(M\)个询问\((u,v,k)\),你需要回答\(u\) \(xor\) \(lastans\)和\( ...
- BZOJ 2588 Count on a tree (COT) 是持久的段树
标题效果:两棵树之间的首次查询k大点的权利. 思维:树木覆盖树,事实上,它是正常的树木覆盖了持久段树. 由于使用权值段树可以寻求区间k大,然后应用到持久段树思想,间隔可以做减法.详见代码. CODE: ...
- BZOJ.2588.Count on a tree(主席树 静态树上第k小)
题目链接 /* 序列上的主席树 某点是利用前一个点的根建树 同理 树上的主席树 某个节点可以利用其父节点(is unique)的根建树 排名可以利用树上前缀和求得: 对于(u,v),w=LCA(u,v ...
- 2588: Count on a tree
敢问和zwt的树有何区别..改了读入直接交..四百个人A,三百多个PE..于是果断贡献几发PE.. http://ideone.com/9XCg3D
- 【BZOJ】【2588】COT(Count On a Tree)
可持久化线段树 maya……树么……转化成序列……所以就写了个树链剖分……然后每个点保存的是从它到根的可持久化线段树. 然后就像序列一样查询……注意是多个左端点和多个右端点,处理方法类似BZOJ 19 ...
- BZOJ 2588: Spoj 10628. Count on a tree [树上主席树]
2588: Spoj 10628. Count on a tree Time Limit: 12 Sec Memory Limit: 128 MBSubmit: 5217 Solved: 1233 ...
- BZOJ 2588: Spoj 10628. Count on a tree 树上跑主席树
2588: Spoj 10628. Count on a tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/J ...
- Bzoj 2588: Spoj 10628. Count on a tree 主席树,离散化,可持久,倍增LCA
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2588 2588: Spoj 10628. Count on a tree Time Limit ...
- BZOJ 2588: Spoj 10628. Count on a tree( LCA + 主席树 )
Orz..跑得还挺快的#10 自从会树链剖分后LCA就没写过倍增了... 这道题用可持久化线段树..点x的线段树表示ROOT到x的这条路径上的权值线段树 ----------------------- ...
随机推荐
- MySQL .msi 安装失败改用.zip安装步骤
一开始官网下载.msi安装包,安装到配置server时无法启动,长时间卡在这里,无法继续下去.上网看了一下解决办法,发现用.zip安装包进行安装比较简单可靠. 一.利用.msi安装包安装失败后的处理 ...
- powershell 监控, 重启网卡
#powershell 监控, 重启网卡 一台Windows服务器,由于负荷较大,偶尔会网络中断,就写了个powershell脚本,监控ip是否通,不通就重启网卡 cls $host.UI.RawUI ...
- “核弹级”Android漏洞Janus,黑客可以任意篡改App
美国时间12月9日,Google披露了一个名为"Janus"安卓漏洞.该漏洞可以让攻击者绕过安卓签名机制,从而让攻击者对App进行篡改,安卓5.0到8.0等个版本系统均受影响. 顶 ...
- RBAC(Role-Based Access Control,基于角色的权限访问控制)—权限管理设计
RBAC模型的核心是在用户和权限之间引入了角色的概念,将用户和权限进行解耦,采用用户确定角色,角色分配权限,进而间接达到给用户分配角色的目的 这样采用的方式优点在于 (1)降低管理成本--由于一个角色 ...
- zzuli 2131 Can Win dinic+链式前向星(难点:抽象出网络模型+建边)
2131: Can Win Time Limit: 1 Sec Memory Limit: 128 MB Submit: 431 Solved: 50 SubmitStatusWeb Board ...
- nginx使用ssl模块配置支持HTTPS访问【解决ssl错误】
默认情况下ssl模块并未被安装,如果要使用该模块则需要在编译nginx时指定–with-http_ssl_module参数. 需求:做一个网站域名为 www.localhost.cn 要求通过http ...
- 使用fastdfs-zyc监控FastDFS文件系统
1.安装jdk运行环境 jdk下载地址:http://www.oracle.com/technetwork/java/javase/downloads/index.html 此处我使用的jdk7U99 ...
- 非常棒的教程记录(UML)
这里暂且记录下看过的非常棒的博客吧! 来自 CSDN 几年前的博客专栏了,我只想说:经典实用的知识永远不会过时! http://blog.csdn.net/column/details/umlmode ...
- Windows下编译nginx-rtmp-module
http://nginx.org/en/docs/howto_build_on_win32.html 官网上的操作说明. 官网的方法Nginx编译方法,思路是一致的,只是有几个细节地方需要调整. 需要 ...
- python模块 - re模块使用演示样例
http://blog.csdn.net/pipisorry/article/details/46619179 re模块匹配规则见:http://blog.csdn.net/pipisorry/art ...