【主席树】【最近公共祖先】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行每 ...
随机推荐
- C#利用WebClient 两种方式下载文件
WebClient client = new WebClient(); 第一种 string URLAddress = @"http://files.cnblogs.com/x4646/tr ...
- Laravel 调试器 Debugbar 和数据库导出利器 DbExporter 扩展安装及注意事项
一.Debugbar安装 参考:Laravel 调试利器 —— Laravel Debugbar 扩展包安装及使用教程 的“2.安装”部分 二.DbExporter安装 参考:Laravel 扩展推荐 ...
- 获取并编译最新的Notepad++源码
获取并编译最新的Notepad++源码 http://blog.csdn.net/u012814856/article/details/68947310 Notepad++源码编译及其分析 http: ...
- C++ 模板的用法
C++中的高阶手法就会用到泛型编程,主要有函数模板, 在程序中使用模板的好处就是在定义时不需要指定具体的参数类型,而在使用时确可以匹配其它任意类型, 定义格式如下 template <class ...
- 从设计图到CSS:rem+viewport+媒体查询+Sass
根据UI图对移动端的h5页面做样式重构,是前端工程师的本职工作,看似简单,不过想做好却并不容易.下面总结一下其中要点. rem rem是一种相对长度单位,参考的基准是<html>标签定义的 ...
- 机器学习方法(六):随机森林Random Forest,bagging
欢迎转载,转载请注明:本文出自Bin的专栏blog.csdn.net/xbinworld. 技术交流QQ群:433250724,欢迎对算法.技术感兴趣的同学加入. 前面机器学习方法(四)决策树讲了经典 ...
- redis之(十四)redis的主从复制的原理
一:redis主从复制的原理,步骤. 第一步:复制初始化 --->从redis启动后,会根据配置,向主redis发送SYNC命令.2.8版本以后,发送PSYNC命令. --->主red ...
- Google的C++开源代码项
转:http://blog.csdn.net/wenrenhua08/article/details/40040903 v8 - V8 JavaScript EngineV8 是 Google 的 ...
- 走进 Akka.NET
官方文档:https://getakka.net/index.html 官网:https://petabridge.com/ 一.Akka.NET 是什么? Akka 是一个构建高并发.分布式和弹性消 ...
- windows安装elasticsearch和elasticsearch-head插件
1.去官网下载最新软件 选择zip包,https://www.elastic.co/downloads/elasticsearch 2.下载node 必须 > 6.0已上 3.解压elastic ...