这题一开始把我看愣了。难道是线段树套树状数组?空间根本开不下好不好!!!

后来想到维护区间极值,从而排除不必要情况,降低复杂度。

无需修改,码量顿减……

注意,同一组数据放一行,注意行末空格。

#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的更多相关文章

  1. hdu6162(树链剖分)

    hdu6162 题意 给出一颗带点权的树,每次询问一对节点 \((u, v)\),问 \(u\) 到 \(v\) 的最短路径上所有节点权值在 \([c1, c2]\) 区间内的和. 分析 树链剖分,那 ...

  2. hdu6162 Ch’s gift

    地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=6162 题目: Ch’s gift Time Limit: 6000/3000 MS (Java ...

  3. 【主席树】【最近公共祖先】hdu6162 Ch’s gift

     题意:一棵树,每个点有个权值,m次询问,每次给你一条链和两个值a,b,问你这条链上权值在[a,b]之间的权值的和是多少. std竟然是2个log的……完全没必要链剖,每个结点的主席树从其父节点转移过 ...

随机推荐

  1. ATL的GUI程序设计(3)

    第三章 ATL的窗口类 CWindowImpl.CWindow.CWinTraits,ATL窗口类的奥秘尽在此三者之中.在本章里,李马将为你详细解说它们的使用方法.另外,本章的内容也可以算是本书的核心 ...

  2. what is muxing and demuxing

    They're short for multiplexing and demultiplexing. Multiplexing means combining different types of d ...

  3. 发生android.view.ViewRoot$CalledFromWrongThreadException异常的解决方案

    在Android平台下,进行多线程编程时,经常需要在主线程之外的一个单独的线程中进行某些处理,然后更新用户界面显示.但是,在主线线程之外的线程中直接更新页面显示的问题是 报异常:android.vie ...

  4. C语言中typedef用法

    C语言中typedef用法 1. 基本解释 typedef为C语言的关键字,作用是为一种数据类型定义一个新名字.这里的数据类型包括内部数据类型(int,char等)和自定义的数据类型(struct等) ...

  5. 视觉slam十四讲第七章课后习题7

    版权声明:本文为博主原创文章,转载请注明出处:http://www.cnblogs.com/newneul/p/8544369.html  7.题目要求:在ICP程序中,将空间点也作为优化变量考虑进来 ...

  6. 视觉slam十四讲ch5 joinMap.cpp 代码注释(笔记版)

    #include <iostream> #include <fstream> using namespace std; #include <opencv2/core/co ...

  7. OpenGL学习网址2

    http://www.opengpu.org/forum.php?mod=viewthread&tid=7525

  8. c++利用初始化列表在类内部和类外部定义构造函数的区别

    case 1:在类外定义构造函数,所有data member都在初始化列表中进行初始化. class SupportClass { public: SupportClass() { cout < ...

  9. 微信小程序面试题总结

    A类问题 1 请谈谈微信小程序主要目录和文件的作用? project.config.json 项目配置文件,用得最多的就是配置是否开启https校验: App.js 设置一些全局的基础数据等: App ...

  10. Python 钩子函数详解

    ###### 钩子函数 ``` import pluggy hookspec = pluggy.HookspecMarker('aaa') hookimpl = pluggy.HookimplMark ...