1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
| #include<bits/stdc++.h> using namespace std; typedef pair <int,int> Pii; #define rep(i,a,b) for(int i=a,i##end=b;i<=i##end;++i) #define drep(i,a,b) for(int i=a,i##end=b;i>=i##end;--i)
char IO; template <class T=int> T rd(){ T s=0; int f=0; while(!isdigit(IO=getchar())) f|=IO=='-'; do s=(s<<1)+(s<<3)+(IO^'0'); while(isdigit(IO=getchar())); return f?-s:s; }
const int N=6e5+10,P=1e9+7;
int n,m; struct Edge{ int to,nxt; }e[N]; int head[N],ecnt; void AddEdge(int u,int v) { e[++ecnt]=(Edge){v,head[u]}; head[u]=ecnt; } int id[N],dfn;
typedef unsigned U; U A[N]; int L[N],K[N]; U Sum,Ans[N]; int dep[N];
void dfs(int u,int f) { L[id[u]=++dfn]=u,K[dfn]=1; dep[u]=dep[f]+1; for(int i=head[u];i;i=e[i].nxt) { int v=e[i].to; if(v==f) continue; dfs(v,u); } L[++dfn]=u,K[dfn]=-1; }
int len; struct Que{ int l,r,id; bool operator < (const Que __) const { if(l/len!=__.l/len) return l/len<__.l/len; return ((l/len)&1)?r<__.r:r>__.r; } } Q[N];
U S[2][N]; void Add(int d,int x,int k) { int p=dep[x]; Sum-=S[d][p]*S[!d][p]; S[d][p]=k==1?A[x]:0; Sum+=S[d][p]*S[!d][p]; }
int main() { n=rd(),m=rd(); rep(i,1,n) A[i]=rd(); rep(i,2,n) { int u=rd(),v=rd(); AddEdge(u,v),AddEdge(v,u); } dfs(1,0),len=sqrt(dfn); rep(i,1,m) { int l=rd(),r=rd(); l=id[l],r=id[r]; if(l>r) swap(l,r); Q[i]=(Que){l,r,i}; } sort(Q+1,Q+m+1); int l=1,r=1; Add(0,1,1),Add(1,1,1); rep(i,1,m) { while(l<Q[i].l) ++l,Add(0,L[l],K[l]); while(l>Q[i].l) Add(0,L[l],-K[l]),l--; while(r<Q[i].r) ++r,Add(1,L[r],K[r]); while(r>Q[i].r) Add(1,L[r],-K[r]),r--; Ans[Q[i].id]=Sum; } rep(i,1,m) printf("%u\n",Ans[i]); }
|