题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6162

题意:给出一棵树的链接方法,每个点都有一个数字,询问U-》V节点经过所有路径中l < = x < = r的数字和

解法:主席树维护区间和,树剖查询,复杂度nloglog。

代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
const int maxm = 40*maxn;
typedef long long LL;
int T[maxn];
int lson[maxm],rson[maxm];
LL sum[maxm];
int clk,M;
int newnode(){
clk++;
lson[clk]=rson[clk]=sum[clk]=0;
return clk;
}
void update(int &now, int pre, int L, int R, int pos, int val)
{
now = newnode();
lson[now] = lson[pre];
rson[now] = rson[pre];
sum[now] = sum[pre] + val;
if(L!=R){
int mid=(L+R)>>1;
if(pos<=mid) update(lson[now],lson[pre],L,mid,pos,val);
else update(rson[now],rson[pre],mid+1,R,pos,val);
}
}
LL query(int rt, int L, int R, int l, int r){
if(l<=L&&R<=r){
return sum[rt];
}
else{
int mid = (L+R)>>1;
LL ret = 0;
if(l <= mid) ret += query(lson[rt], L, mid, l, r);
if(mid < r) ret += query(rson[rt], mid+1, R, l, r);
return ret;
}
}
struct edge{
int to,next;
}E[maxn*2];
int head[maxn],edgecnt,tim;
int siz[maxn],top[maxn],son[maxn],dep[maxn];
int fa[maxn],tid[maxn],Rank[maxn],val[maxn];
void init(){
edgecnt=tim=0;
memset(head,-1,sizeof(head));
memset(son,-1,sizeof(son));
clk=M=0;
lson[clk]=rson[clk]=sum[clk]=0;
}
void add(int u, int v){
E[edgecnt].to=v,E[edgecnt].next=head[u],head[u]=edgecnt++;
}
void dfs1(int u, int pre, int d){
dep[u]=d;
fa[u]=pre;
siz[u]=1;
for(int i=head[u];~i;i=E[i].next){
int v=E[i].to;
if(v!=pre){
dfs1(v,u,d+1);
siz[u]+=siz[v];
if(son[u]==-1||siz[v]>siz[son[u]]) son[u]=v;
}
}
}
void dfs2(int u, int tp){
top[u]=tp;
tid[u]=++tim;
Rank[tid[u]]=u;
if(son[u]==-1) return;
dfs2(son[u],tp);
for(int i=head[u];~i;i=E[i].next){
int v=E[i].to;
if(v!=son[u]&&v!=fa[u]){
dfs2(v,v);
}
}
}
int LCA(int u, int v)
{
int ret;
while(true)
{
if(top[u] == top[v])
{
ret = dep[u] < dep[v] ? u : v;
break;
}
else if(dep[top[u]] > dep[top[v]])
u = fa[top[u]];
else v = fa[top[v]];
}
return ret;
}
int t[maxn];
LL query(int u, int v, int a, int b)
{
a = lower_bound(t + 1, t + 1 + M, a) - t - 1;
b = upper_bound(t + 1, t + 1 + M, b) - t - 1;
if(b == 0)
return 0;
LL ret = 0;
while(top[u] != top[v])
{
if(dep[top[u]] < dep[top[v]])
swap(u, v);
ret += query(T[tid[u]], 1, M, 1, b);
ret -= query(T[tid[top[u]] - 1], 1, M, 1, b);
if(a)
{
ret -= query(T[tid[u]], 1, M, 1, a);
ret += query(T[tid[top[u]] - 1], 1, M, 1, a);
}
u = fa[top[u]];
}
if(dep[u] < dep[v])
swap(u, v);
ret += query(T[tid[u]], 1, M, 1, b);
ret -= query(T[tid[v] - 1], 1, M, 1, b);
if(a)
{
ret -= query(T[tid[u]], 1, M, 1, a);
ret += query(T[tid[v] - 1], 1, M, 1, a);
}
return ret;
}
int main()
{
int n,m;
while(~scanf("%d %d",&n,&m))
{
init();
for(int i=1; i<=n; i++){
scanf("%d", &val[i]);
t[i]=val[i];
}
for(int i=1; i<n; i++){
int u,v;
scanf("%d %d", &u,&v);
add(u, v);
add(v, u);
}
dfs1(1,0,0);
dfs2(1,1);
sort(t+1,t+n+1);
M = unique(t+1, t+n+1)-t-1;
for(int i=1; i<=n; i++) val[i] = lower_bound(t+1, t+1+M, val[i])-t;
for(int i=1; i<=n; i++){
T[i] = T[i-1];
update(T[i],T[i],1,M,val[Rank[i]],t[val[Rank[i]]]);
}
for(int i=1; i<=m; i++){
int u,v,x,y;
scanf("%d %d %d %d", &u,&v,&x,&y);
LL ret = query(u,v,x,y);
printf("%lld", ret);
if(i == m){
printf("\n");
}
else{
printf(" ");
}
}
}
return 0;
}

2017多校第9场 HDU 6162 Ch’s gift 树剖加主席树的更多相关文章

  1. 2017多校第9场 HDU 6161 Big binary tree 思维,类似字典树

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6161 题意: 题目是给一棵完全二叉树,从上到下从左到右给每个节点标号,每个点有权值,初始权值为其标号, ...

  2. HDU 6162 - Ch’s gift | 2017 ZJUT Multi-University Training 9

    /* HDU 6162 - Ch’s gift [ LCA,线段树 ] | 2017 ZJUT Multi-University Training 9 题意: N节点的树,Q组询问 每次询问s,t两节 ...

  3. 2017 Multi-University Training Contest - Team 9 1002&&HDU 6162 Ch’s gift【树链部分+线段树】

    Ch’s gift Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total S ...

  4. 2017多校第9场 HDU 6170 Two strings DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6170 题意:给了2个字符串,其中第2个字符串包含.和*两种特别字符,问第二个字符串能否和第一个匹配. ...

  5. 2017多校第9场 HDU 6169 Senior PanⅡ 数论,DP,爆搜

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6169 题意:给了区间L,R,求[L,R]区间所有满足其最小质数因子为k的数的和. 解法: 我看了这篇b ...

  6. 2017多校第10场 HDU 6181 Two Paths 次短路

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6181 题意:给一个图,求出次短路. 解法:我之前的模板不能解决这种图,就是最短路和次短路相等的情况,证 ...

  7. 2017多校第10场 HDU 6180 Schedule 贪心,multiset

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6180 题意:给了一些任务的开始时间和终止时间,现在让我们安排k台及机器,让这些任务在k太机器上最小,并 ...

  8. 2017多校第10场 HDU 6178 Monkeys 贪心,或者DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6178 题意:给出一棵有n个节点的树,现在需要你把k只猴子放在节点上,每个节点最多放一只猴子,且要求每只 ...

  9. 2017多校第10场 HDU 6171 Admiral 双向BFS或者A*搜索

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6171 题意: 给你一个高度为6的塔形数组,你每次只能将0与他上下相邻的某个数交换,问最少交换多少次可以 ...

随机推荐

  1. linux文件服务器:samba服务器

    windows上,需要和linux虚拟机进行方便的文件交互,总结一下遇到的问题. 1.samba简介 windows和windows之间共享文件可以用“网上邻居”,linux和linux间共享文件用 ...

  2. hihoCoder#1698 : 假期计划 组合数

    题面:hihoCoder#1698 : 假期计划  组合数 题解: 题目要求是有序的排列,因此我们可以在一开始就乘上A!*B!然后在把这个序列划分成很多段. 这样的话由于乘了阶乘,所以所有排列我们都已 ...

  3. Python type()函数用途及使用方法

    函数可以做什么 在介绍数据类型的文章中提到过,要怎么样查看对像的数据类型.type()就是一个最实用又简单的查看数据类型的方法.type()是一个内建的函数,调用它就能够得到一个反回值,从而知道想要查 ...

  4. POJ. 2253 Frogger (Dijkstra )

    POJ. 2253 Frogger (Dijkstra ) 题意分析 首先给出n个点的坐标,其中第一个点的坐标为青蛙1的坐标,第二个点的坐标为青蛙2的坐标.给出的n个点,两两双向互通,求出由1到2可行 ...

  5. nfs挂载权限问题

    问题: 服务器A:192.168.10.230 服务器B:192.168.10.231 由于服务器A空间不足,打算将服务器A产生的数据库日志挂载到服务器B上,刚开始设定的anonuid和anongid ...

  6. 使用Spring Animation的API创建动画

    pring Animation 是一种特殊的动画曲线,自从 iOS 7 开始被广泛应用在系统动画中. Spring Animation 是Linear(线性即匀速)动画.Ease-out(即动画减速地 ...

  7. DFS搜索题素数环

    素数环: 输入整数1,2,3,4,5,···,n组成一个环,使得相邻两个整数之和均为素数. 输出时从整数1开始逆时针排列.同一个环应恰好输出一次.n<=16. Sample: input: 6 ...

  8. Microsoft office 2013安装图解

    Microsoft office 2013安装图解... ================ 简介: Microsoft Office 2013(Office 15)是微软的新一代Office办公软件, ...

  9. Android 自定义ListView实现底部分页刷新与顶部下拉刷新,androidlistview

    在项目开发中,由于数据过大时,需要进行分页加载或下拉刷新,来缓解一次性加载的过长等待.本篇博文实例讲解通过自定义的ListView实现底部分页加载和顶部下拉刷新的效果. 其效果图: 一.ListVie ...

  10. [freemarker篇]02.生成HTML的静态页面

    昨天完成了一部分的今天在上次的基础上,完成完成生成HTML静态页面的操作,中间会涉及一点标签的简单使用.今天的代码有一丢丢的对付的感觉!抱歉了,直接就上代码吧!求原谅! 项目结构目录如下: 第一步,新 ...