using namespace std; int n,q,step; LL w[maxn]; int sz[maxn],dep[maxn],fa[maxn],son[maxn]; int id[maxn],top[maxn]; int val[maxn]; struct T{ LL sum,Max,Min; }tree[maxn<<2]; vector<int>e[maxn]; void init(){ for(int i=0;i<=n;i++) e[i].clear(); mm(sz,0),mm(dep,0),mm(fa,0),mm(son,0); mm(id,0),mm(top,0),mm(val,0); mm(tree,0); step=0; } void dfs1(int x,int f,int deep){ sz[x]=1,fa[x]=f,son[x]=0,dep[x]=deep; int len=e[x].size(); for(int i=0;i<len;i++){ int next=e[x][i]; if(next==f) continue; dfs1(next,x,deep+1); sz[x]+=sz[next]; if(sz[son[x]]<sz[next]) son[x]=next; } } void dfs2(int x,int tp){ top[x]=tp; id[x]=++step; val[id[x]]=x; if(son[x]) dfs2(son[x],tp); int len=e[x].size(); for(int i=0;i<len;i++){ int next=e[x][i]; if(next==fa[x] || next==son[x]) continue; dfs2(next,next); } } void push_up(int rt){ tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum; tree[rt].Max=max(tree[rt<<1].Max,tree[rt<<1|1].Max); tree[rt].Min=min(tree[rt<<1].Min,tree[rt<<1|1].Min); } void build(int rt,int l,int r){ if(l==r){ tree[rt].sum=tree[rt].Max=tree[rt].Min=w[val[l]]; return; } int mid=(l+r)>>1; build(lson); build(rson); push_up(rt); } LL query(int rt,int l,int r,int L,int R,LL x,LL y){ if(l>=L && r<=R){ if(tree[rt].Max<x || tree[rt].Min>y) return 0; if(tree[rt].Max<=y && tree[rt].Min>=x) return tree[rt].sum; } int mid=(l+r)>>1; LL ans=0; if(mid>=L) ans+=query(lson,L,R,x,y); if(mid<R) ans+=query(rson,L,R,x,y); return ans; } LL solve(int L,int R,LL x,LL y){ LL sum=0; while(top[L]!=top[R]){ if(dep[top[L]]<dep[top[R]]) swap(L,R); sum+=query(1,1,n,id[top[L]],id[L],x,y); L=fa[top[L]]; } if(id[L]>id[R]) swap(L,R); sum+=query(1,1,n,id[L],id[R],x,y); return sum; } int main(){ // freopen("input.txt","r",stdin); while(scanf("%d%d",&n,&q)!=EOF){ init(); for(int i=1;i<=n;i++) scanf("%d",&w[i]); for(int i=1;i<n;i++){ int u,v; scanf("%d%d",&u,&v); e[u].push_back(v); e[v].push_back(u); } dfs1(1,0,0); dfs2(1,1); build(1,1,n); while(q--){ int s,t; LL a,b; scanf("%d%d%lld%lld",&s,&t,&a,&b); LL ans=solve(s,t,a,b); if(q==0) printf("%lld\n",ans); else printf("%lld ",ans); } } return 0; }
|