hdu6162
这题一开始把我看愣了。难道是线段树套树状数组?空间根本开不下好不好!!!
后来想到维护区间极值,从而排除不必要情况,降低复杂度。
无需修改,码量顿减……
注意,同一组数据放一行,注意行末空格。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=;
int n,m,val[maxn];
int beg[maxn],nex[maxn],to[maxn],e;
void add(int x,int y){
e++;nex[e]=beg[x];
beg[x]=e;to[e]=y;
}
int son[maxn],size[maxn],dep[maxn],f[maxn];
void dfs1(int x,int fa){
dep[x]=dep[fa]+;
f[x]=fa;
size[x]=;
son[x]=;
for(int i=beg[x];i;i=nex[i]){
int t=to[i];
if(t==fa)continue;
dfs1(t,x);
size[x]+=size[t];
if(size[t]>size[son[x]])
son[x]=t;
}
}
int id[maxn],num[maxn],top[maxn],cnt;
void dfs2(int x,int topc){
id[x]=++cnt;
num[cnt]=val[x];
top[x]=topc;
if(!son[x])return;
dfs2(son[x],topc);
for(int i=beg[x];i;i=nex[i]){
int t=to[i];
if(t==son[x]||t==f[x])
continue;
dfs2(t,t);
}
}
int tr[maxn],mx[maxn],mn[maxn];
void build(int h,int l,int r){
if(l==r){
mx[h]=mn[h]=tr[h]=num[l];
return;
}
int mid=(l+r)>>;
build(h<<,l,mid);
build(h<<|,mid+,r);
tr[h]=tr[h<<]+tr[h<<|];
mx[h]=max(mx[h<<],mx[h<<|]);
mn[h]=min(mn[h<<],mn[h<<|]);
}
int query(int h,int l,int r,int x,int y,int a,int b){
if(l>y||r<x||mx[h]<a||mn[h]>b)return ;
if(l>=x&&r<=y&&mn[h]>=a&&mx[h]<=b)return tr[h];
int mid=(l+r)>>;
return query(h<<,l,mid,x,y,a,b)+query(h<<|,mid+,r,x,y,a,b);
}
int qc(int x,int y,int a,int b){
int ans=;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
ans+=query(,,n,id[top[x]],id[x],a,b);
x=f[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
ans+=query(,,n,id[x],id[y],a,b);
return ans;
}
signed main(){
while(scanf("%lld%lld",&n,&m)!=EOF){
e=cnt=;
memset(beg,,sizeof(beg));
for(int i=;i<=n;i++)
scanf("%lld",&val[i]);
int x,y;
for(int i=;i<n;i++){
scanf("%lld%lld",&x,&y);
add(x,y),add(y,x);
}
dfs1(,);
dfs2(,);
build(,,n);
int a,b;
for(int i=;i<=m;i++){
scanf("%lld%lld%lld%lld",&x,&y,&a,&b);
printf("%lld",qc(x,y,a,b));
if(i!=m)printf(" ");
}
puts("");
}
return ;
}
深深地感到自己的弱小。
hdu6162的更多相关文章
- hdu6162(树链剖分)
hdu6162 题意 给出一颗带点权的树,每次询问一对节点 \((u, v)\),问 \(u\) 到 \(v\) 的最短路径上所有节点权值在 \([c1, c2]\) 区间内的和. 分析 树链剖分,那 ...
- hdu6162 Ch’s gift
地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=6162 题目: Ch’s gift Time Limit: 6000/3000 MS (Java ...
- 【主席树】【最近公共祖先】hdu6162 Ch’s gift
题意:一棵树,每个点有个权值,m次询问,每次给你一条链和两个值a,b,问你这条链上权值在[a,b]之间的权值的和是多少. std竟然是2个log的……完全没必要链剖,每个结点的主席树从其父节点转移过 ...
随机推荐
- 死磕java(2)
java数据类型 boolean --true--false byte --8位 short --16位 int --32位 long --64位 char float --32位 double -- ...
- java核心技术----访问权限
Java支持四种不同的访问权限: 修饰符 说明 public 共有的,对所有类可见 protected 受保护的,对同一包内的类和所有子类可见 private 私有的,在同一类内可见 默认的 在同一包 ...
- LUA学习笔记(第5-6章)
x = a or b 如果a为真则x = a 如果a为假则x = b print(a .. b) 任何非nil类型都会被连接为字符串,输出 多重返回值 local s,e = string.find( ...
- POJ_1185_状态压缩dp
http://poj.org/problem?id=1185 一次考虑两行,比一行略为复杂.sta保存每种状态炮兵位置,sum保存每种状态当行炮兵总数,a保存地形,dp[i][j][k]表示到第i行当 ...
- PHP第三方登录——QQ登录
主要内容 简单回顾OAuth协议基本原理 接入QQ登录的前置条件以及开放平台账号申请 引入官方SDK SDK参数配置 SDK核心方法解读 整合QQ登录SDK到Web应用中 SDK优化 调用API的开发 ...
- 【题解】P1020 导弹拦截
[题解]P1020 导弹拦截 从n^2到nlogn 第二问就是贪心,不多说 第一问: 简化题意:求最长不下降子序列 普通n^2: for (int i = 1; i <= n; i++) for ...
- Python Special Methods - 特殊方法
特殊方法 特殊方法的存在是为了给 Python 解释器调用的,通常自己并不需要直接调用它们.也就是说不应该使用 my_object.__len__() 这种写法,而应该使用 len(my_object ...
- 面向对象之包装类与Object类
一.包装类(Wrapper) 1.包装类出现原因 为了使8种基本数据类型的变量具有类的特征,引入包装类 2.类型间转化 ① 基本数据类型---->对应的包装类:自动装箱 包装类---->对 ...
- pos 访问超时 windows连接超时 497 天后未关闭 TIME_WAIT
问题描述: nginx连接后台tomcat程序 一直报错 nginx的error日志如下 // :: [error] #: *: A connection attempt failed because ...
- 交换机 路由器 防火墙asa 安全访问、配置 方式
这里交换机 路由器 暂时统称为 网络设备 我们一般管理网络设备采用的几种方法 一般来说,可以用5种方式来设置路由器: 1. Console口接终端或运行终端仿真软件的微机(第一次配置要使用此方式) ...