【HDU 6162】 Ch’s gift
【题目链接】
http://acm.hdu.edu.cn/showproblem.php?pid=6162
【算法】
离线树剖
我们知道,u到v路径上权值为[A,B]的数的和 = u到v路径上权值小于等于B的数的和 - u到v路径上权值小于等于(A-1)的数的和
不妨将询问拆开,离线计算答案即可
【代码】
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + ; int i,n,m,u,v,now,timer,tot,cnt;
long long l,r;
int head[MAXN],size[MAXN],fa[MAXN],top[MAXN],
dep[MAXN],son[MAXN],dfn[MAXN];
long long ans[MAXN]; struct Edge
{
int to,nxt;
} e[MAXN<<];
struct info
{
int val,pos;
} a[MAXN];
struct Query
{
int u,v;
long long m;
int flag,id;
} q[MAXN<<]; struct SegmentTree
{
struct Node
{
int l,r;
long long sum;
} Tree[MAXN<<];
inline void build(int index,int l,int r)
{
int mid;
Tree[index] = (Node){l,r,};
if (l == r) return;
mid = (l + r) >> ;
build(index<<,l,mid);
build(index<<|,mid+,r);
}
inline void update(int index)
{
Tree[index].sum = Tree[index<<].sum + Tree[index<<|].sum;
}
inline void add(int index,int pos,long long val)
{
int mid;
if (Tree[index].l == Tree[index].r)
{
Tree[index].sum += val;
return;
}
mid = (Tree[index].l + Tree[index].r) >> ;
if (mid >= pos) add(index<<,pos,val);
else add(index<<|,pos,val);
update(index);
}
inline long long query(int index,int l,int r)
{
int mid;
if (Tree[index].l == l && Tree[index].r == r) return Tree[index].sum;
mid = (Tree[index].l + Tree[index].r) >> ;
if (mid >= r) return query(index<<,l,r);
else if (mid + <= l) return query(index<<|,l,r);
else return query(index<<,l,mid) + query(index<<|,mid+,r);
}
} T;
inline bool cmp1(info a,info b)
{
return a.val < b.val;
}
inline bool cmp2(Query a,Query b)
{
return a.m < b.m;
}
inline void add(int u,int v)
{
tot++;
e[tot] = (Edge){v,head[u]};
head[u] = tot;
}
inline void dfs1(int u)
{
int i,v;
size[u] = ;
for (i = head[u]; i; i = e[i].nxt)
{
v = e[i].to;
if (fa[u] != v)
{
fa[v] = u;
dep[v] = dep[u] + ;
dfs1(v);
size[u] += size[v];
if (size[v] > size[son[u]]) son[u] = v;
}
}
}
inline void dfs2(int u,int tp)
{
int i,v;
top[u] = tp;
dfn[u] = ++timer;
if (son[u]) dfs2(son[u],tp);
for (i = head[u]; i; i = e[i].nxt)
{
v = e[i].to;
if (fa[u] != v && son[u] != v) dfs2(v,v);
}
}
inline long long query(int u,int v)
{
int tu = top[u],
tv = top[v];
long long ret = ;
while (tu != tv)
{
if (dep[tu] > dep[tv])
{
swap(u,v);
swap(tu,tv);
}
ret += T.query(,dfn[tv],dfn[v]);
v = fa[tv]; tv = top[v];
}
if (dfn[u] > dfn[v]) swap(u,v);
ret += T.query(,dfn[u],dfn[v]);
return ret;
} int main()
{ while (scanf("%d%d",&n,&m) != EOF)
{
timer = ;
tot = ;
for (i = ; i <= n; i++)
{
head[i] = ;
son[i] = ;
}
cnt = ;
memset(ans,,sizeof(ans));
for (i = ; i <= n; i++)
{
scanf("%lld",&a[i].val);
a[i].pos = i;
}
for (i = ; i < n; i++)
{
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
dfs1();
dfs2(,);
T.build(,,timer);
for (i = ; i <= m; i++)
{
scanf("%d%d%lld%lld",&u,&v,&l,&r);
if (l > ) q[++cnt] = (Query){u,v,l-,,i};
q[++cnt] = (Query){u,v,r,,i};
}
sort(a+,a+n+,cmp1);
sort(q+,q+cnt+,cmp2);
now = ;
for (i = ; i <= cnt; i++)
{
while (now <= n && a[now].val <= q[i].m)
{
T.add(,dfn[a[now].pos],a[now].val);
now++;
}
if (q[i].flag == ) ans[q[i].id] -= query(q[i].u,q[i].v);
else ans[q[i].id] += query(q[i].u,q[i].v);
}
for (i = ; i < m; i++) printf("%lld ",ans[i]);
printf("%lld\n",ans[m]);
} return ; }
【HDU 6162】 Ch’s gift的更多相关文章
- 【 2017 Multi-University Training Contest - Team 9 && hdu 6162】Ch’s gift
[链接]h在这里写链接 [题意] 给你一棵树,每个节点上都有一个权值. 然后给你m个询问,每个询问(x,y,a,b); 表示询问x->y这条路径上权值在[a,b]范围内的节点的权值和. [题解] ...
- 【HDU 2196】 Computer(树的直径)
[HDU 2196] Computer(树的直径) 题链http://acm.hdu.edu.cn/showproblem.php?pid=2196 这题可以用树形DP解决,自然也可以用最直观的方法解 ...
- 【HDU 2196】 Computer (树形DP)
[HDU 2196] Computer 题链http://acm.hdu.edu.cn/showproblem.php?pid=2196 刘汝佳<算法竞赛入门经典>P282页留下了这个问题 ...
- 【数位dp】【HDU 3555】【HDU 2089】数位DP入门题
[HDU 3555]原题直通车: 代码: // 31MS 900K 909 B G++ #include<iostream> #include<cstdio> #includ ...
- 【HDU 5647】DZY Loves Connecting(树DP)
pid=5647">[HDU 5647]DZY Loves Connecting(树DP) DZY Loves Connecting Time Limit: 4000/2000 MS ...
- -【线性基】【BZOJ 2460】【BZOJ 2115】【HDU 3949】
[把三道我做过的线性基题目放在一起总结一下,代码都挺简单,主要就是贪心思想和异或的高斯消元] [然后把网上的讲解归纳一下] 1.线性基: 若干数的线性基是一组数a1,a2,a3...an,其中ax的最 ...
- 【HDU 5145】 NPY and girls(组合+莫队)
pid=5145">[HDU 5145] NPY and girls(组合+莫队) NPY and girls Time Limit: 8000/4000 MS (Java/Other ...
- 【hdu 1043】Eight
[题目链接]:http://acm.hdu.edu.cn/showproblem.php?pid=1043 [题意] 会给你很多组数据; 让你输出这组数据到目标状态的具体步骤; [题解] 从12345 ...
- 【HDU 3068】 最长回文
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=3068 [算法] Manacher算法求最长回文子串 [代码] #include<bits/s ...
随机推荐
- easyui 使用笔记
http://www.easyui.info/archives/1435.html datagrid 服务端分页 服务端分页,高效,快捷!强力推荐! easyui的datagrid服务端分页,通过设置 ...
- Discuz! X3.1云平台QQ互联的Unknown column 'conuintoken' in 'field list' 解决办法
http://www.discuz.net/thread-3482497-1-1.html 由于程序安装默认数据表的结构和QQ互联数据表结构不同,安装Discuz! X3.1和升级Discuz! X3 ...
- Windows如何正确的修改administrator用户名
无论是服务器还是电脑.修改默认的administrator的用户总是好的.话不多少.直接上图 1.win+r 输入:gpedit.msc 2.按照我下图的圈圈找到重命名系统管理员账户并自定义 3.重 ...
- python 获取本机环境信息
一.函数 1.socket.gethostname():不带任何参数,返回一个字符串(主机名),通常不完整.比如csm.example.com 只会返回csm 2.socket.getfqdn():带 ...
- js基本类型的包装对象
var test = "test"; test.a = "hello"; console.log(test.a); 在JavaScript中,“一切皆对象”,数 ...
- Python培训时长多久可以学会?马哥教育9年经验之谈
在Python成为一门炙手可热的语言之后,很多人也开始准备向这个行业发展.技术入行也就是培训和自学两条路,各有优劣,不过培训因为学习比较系统比较快也受到不少人欢迎. 今天我就来给大家分享一下Pytho ...
- 比n大的最小不重复数
void Calculate(int a) { int pa = a; ; ] = {}; //将pa按位存储到数组b ) { b[count++] = pa%; pa = pa/; } bool f ...
- C++项目作业 学生管理系统
/*Student.h*/#pragma once #include<string.h> using namespace std; #include<string> class ...
- 基于Ubuntu系统的Tomcat部署项目
第一步.拿到项目war包 第二步.上传到服务器/var/lib/tomcat8/webapps/ROOT目录下 第三步.使用命令解压war包 jar -xvf star1.0.0.war 第三步.重启 ...
- [luoguP2870] [USACO07DEC]最佳牛线,黄金Best Cow Line, Gold(后缀数组)
传送门 数据小的话贪心就行. 可以把这个串翻转再接到后面,再求后缀数组,求出 rank 数组就很简单了. ——代码 #include <cstdio> #include <iostr ...