【主席树】【最近公共祖先】hdu6162 Ch’s gift
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define N 300005
typedef long long ll;
int v[N<<1],first[N],nex[N<<1],en;
void AddEdge(int U,int V)
{
v[++en]=V;
nex[en]=first[U];
first[U]=en;
}
struct Point{int v,p;}t[N];
bool operator < (Point a,Point b){return a.v<b.v;}
int n,m,ma[N],a[N],zy;
struct Node{ll v;int lc,rc;}T[100005*27];
int root[N],e=1;
void BuildTree(int cur,int l,int r)
{
if(l==r) return;
int m=(l+r>>1);
T[cur].lc=++e;
BuildTree(T[cur].lc,l,m);
T[cur].rc=++e;
BuildTree(T[cur].rc,m+1,r);
}
void Insert(int pre,int cur,int p,int v,int l,int r)
{
if(l==r)
{
T[cur].v=T[pre].v+(ll)v;
return;
}
int m=(l+r>>1);
if(p<=m)
{
T[cur].lc=++e;
T[cur].rc=T[pre].rc;
Insert(T[pre].lc,T[cur].lc,p,v,l,m);
}
else
{
T[cur].rc=++e;
T[cur].lc=T[pre].lc;
Insert(T[pre].rc,T[cur].rc,p,v,m+1,r);
}
T[cur].v=T[T[cur].lc].v+T[T[cur].rc].v;
}
int top[N],siz[N],son[N],fa[N],dep[N];
void df1(int U)
{
siz[U]=1;
for(int i=first[U];i;i=nex[i])
if(v[i]!=fa[U])
{
fa[v[i]]=U;
dep[v[i]]=dep[U]+1;
df1(v[i]);
siz[U]+=siz[v[i]];
if(siz[v[i]]>siz[son[U]])
son[U]=v[i];
}
}
void df2(int U)
{
if(son[U])
{
top[son[U]]=top[U];
df2(son[U]);
}
for(int i=first[U];i;i=nex[i])
if(v[i]!=fa[U]&&v[i]!=son[U])
{
top[v[i]]=v[i];
df2(v[i]);
}
}
int lca(int U,int V)
{
while(top[U]!=top[V])
{
if(dep[top[U]]<dep[top[V]])
swap(U,V);
U=fa[top[U]];
}
if(dep[U]>dep[V])
swap(U,V);
return U;
}
void dfs(int U)
{
root[U]=++e;
Insert(root[fa[U]],root[U],a[U],ma[a[U]],1,zy);
for(int i=first[U];i;i=nex[i])
if(v[i]!=fa[U])
dfs(v[i]);
}
ll query(int ql,int qr,int LCA,int FLCA,int A,int B,int l,int r)
{
if(A<=l && r<=B){
return T[ql].v+T[qr].v-T[LCA].v-T[FLCA].v;
}
int m=(l+r>>1);
ll res=0;
if(A<=m)
res+=query(T[ql].lc,T[qr].lc,T[LCA].lc,T[FLCA].lc,A,B,l,m);
if(m<B)
res+=query(T[ql].rc,T[qr].rc,T[LCA].rc,T[FLCA].rc,A,B,m+1,r);
return res;
}
int xs[N],ys[N],as[N],bs[N];
int main()
{
//freopen("b.in","r",stdin);
//freopen("b.out","w",stdout);
int X,Y,W;
while(scanf("%d%d",&n,&m)!=EOF){
e=0;
zy=0;
en=0;
memset(first,0,sizeof(first));
memset(a,0,sizeof(a));
memset(ma,0,sizeof(ma));
memset(t,0,sizeof(t));
memset(T,0,sizeof(T));
memset(root,0,sizeof(root));
memset(top,0,sizeof(top));
memset(son,0,sizeof(son));
memset(siz,0,sizeof(siz));
memset(fa,0,sizeof(fa));
memset(dep,0,sizeof(dep));
for(int i=1;i<=n;++i)
{
scanf("%d",&t[i].v);
t[i].p=i;
}
for(int i=1;i<n;++i)
{
scanf("%d%d",&X,&Y);
AddEdge(X,Y);
AddEdge(Y,X);
}
int all=n;
for(int i=1;i<=m;++i){
scanf("%d%d%d%d",&xs[i],&ys[i],&as[i],&bs[i]);
t[++all].v=as[i];
t[all].p=all;
t[++all].v=bs[i];
t[all].p=all;
}
sort(t+1,t+all+1);
if(t[1].p<=n){
a[t[1].p]=++zy;
}
else{
if((t[1].p-n)%2==1){
as[(t[1].p-n-1)/2+1]=++zy;
}
else{
bs[(t[1].p-n)/2]=++zy;
}
}
ma[zy]=t[1].v;
for(int i=2;i<=all;++i){
if(t[i].v!=t[i-1].v) ++zy;
if(t[i].p<=n){
a[t[i].p]=zy;
}
else{
if((t[i].p-n)%2==1){
as[(t[i].p-n-1)/2+1]=zy;
}
else{
bs[(t[i].p-n)/2]=zy;
}
}
ma[zy]=t[i].v;
}
root[0]=1;
BuildTree(root[0],1,zy);
df1(1);
top[1]=1;
df2(1);
dfs(1);
for(int i=1;i<=m;++i){
X=xs[i];
Y=ys[i];
int t=lca(X,Y);
printf("%lld%c",query(root[X],root[Y],root[t],root[fa[t]],as[i],bs[i],1,zy),i==m?'\n':' ');
}
}
return 0;
}
【主席树】【最近公共祖先】hdu6162 Ch’s gift的更多相关文章
- hdu6162 Ch’s gift
地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=6162 题目: Ch’s gift Time Limit: 6000/3000 MS (Java ...
- 马路 树链剖分/线段树/最近公共祖先(LCA)
题目 [问题描述] 小迟生活的城市是⼀棵树(树指的是⼀个含有 \(n\) 个节点以及 \(n-1\) 条边的⽆向连通图),节点编号从 \(1\) 到 \(n\),每条边拥有⼀个权值 \(value\) ...
- 【bzoj2588】Spoj 10628. Count on a tree 离散化+主席树
题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始为0,即第一个 ...
- Hihocoder #1067 : 最近公共祖先·二
时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上上回说到,小Hi和小Ho用非常拙劣——或者说粗糙的手段山寨出了一个神奇的网站,这个网站可以计算出某两个人的所有共同祖先中 ...
- 51 nod 1681 公共祖先 (主席树+dfs序)
1681 公共祖先 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 有一个庞大的家族,共n人.已知这n个人的祖辈关系正好形成树形结构(即父亲向儿子连边). 在另 ...
- 0x63树的直径与最近公共祖先
凉 bzoj1999 先把树的直径求出来,从左往右枚举,对于当前位置i,找到满足限制并且最远的点j,当前位置最大值就是max(i~j区间内除直径外的子树路径长度最大值,1~i的长度,j~n的长度) 然 ...
- 线段树、最短路径、最小生成树、并查集、二分图匹配、最近公共祖先--C++模板
线段树(区间修改,区间和): #include <cstdio> #include <iostream> #include <cstring> using name ...
- 【并查集】【树】最近公共祖先LCA-Tarjan算法
最近公共祖先LCA 双链BT 如果每个结点都有一个指针指向它的父结点,于是我们可以从任何一个结点出发,得到一个到达树根结点的单向链表.因此这个问题转换为两个单向链表的第一个公共结点(先分别遍历两个链表 ...
- 洛谷P3379 【模板】最近公共祖先(LCA)(树链剖分)
题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每 ...
随机推荐
- perl6中的hash定义(1)
,,,); say %hash; , b => ); say %hash2; my %hash3 = (:name('root'), :host('localost')); say %hash3 ...
- /proc/diskstats文件注解
/proc/diskstats 注解 今儿在准备利用shell监控磁盘读写次数等信息时,看到该文件,但是又不清楚每段的具体含义,这里备注下. 文件内容 [root@namenode proc]# ca ...
- Python模块学习 - Argparse
argparse模块 在Python中,argparse模块是标准库中用来解析命令行参数的模块,用来替代已经过时的optparse模块.argparse模块能够根据程序中的定义从sys.argv中解析 ...
- 【Python学习】使用Pyinstaller将py文件导出为exe文件
PyInstaller其实就是把python解析器和你自己的脚本打包成一个可执行的文件,但是它不是跨编译的,也就是说在Windows下用PyInstaller生成的exe只能运行在Windows下,在 ...
- Vuex 基本概念
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化. 每一个 Vuex 应用的核心就是 stor ...
- Shell脚本中引用、调用另一个脚本文件的2种方法
Shell脚本中引用.调用另一个脚本文件的2种方法 http://www.jb51.net/article/67903.htm
- Oracle with重用子查询
--with 重用子查询对于多次使用相同子查询的复杂查询语句来说,用户可能会将查询语句分成两条语句执行.第一条语句将子查询结果存放到临时表,第二条查询语句使用临时表处理数据.从 Oracle 9i 开 ...
- 一个真正的客户端非阻塞的 connect
前言 - 一个简短开场白 winds 的 select 和 linux 的 select 是两个完全不同的东西. 然而凡人喜欢把它们揉在一起. 非阻塞的connect业务是个自带超时机制的 conn ...
- 在Caffe中使用 DIGITS(Deep Learning GPU Training System)自定义Python层
注意:包含Python层的网络只支持单个GPU训练!!!!! Caffe 使得我们有了使用Python自定义层的能力,而不是通常的C++/CUDA.这是一个非常有用的特性,但它的文档记录不足,难以正确 ...
- JMeter 中 HTTP Cookie 管理器的使用
根据 web 应用的复杂度你可以选择创建两种类型的 JMeter 测试计划:面向点击数的或面向场景的. 创建一个面向点击数的测试计划你需要有中值统计.这些统计要包含你的应用每秒应该处理多少个独立请求的 ...