lca+树上差分
#include<vector>
#include<cstdio>
#include<algorithm>
#define rg register
#define ci const int
#define cl const long long int
typedef long long int ll;
namespace IO {
char buf[90];
}
template<typename T>
inline void qr(T &x) {
char ch=getchar(),lst=' ';
while(ch>'9'||ch<'0') lst=ch,ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
if(lst=='-') x=-x;
}
template<typename T>
inline void write(T x,const char aft,const bool pt) {
if(x<0) x=-x,putchar('-');
int top=0;
do {
IO::buf[++top]=x%10+'0';
x/=10;
} while(x);
while(top) putchar(IO::buf[top--]);
if(pt) putchar(aft);
}
template<typename T>
inline T mmax(const T a,const T b) {if(a>b) return a;return b;}
template<typename T>
inline T mmin(const T a,const T b) {if(a<b) return a;return b;}
template<typename T>
inline T mabs(const T a) {if(a<0) return -a;return a;}
template<typename T>
inline void mswap(T &a,T &b) {
T temp=a;a=b;b=temp;
}
const int maxn = 1000010;
const int maxm = 1000010;
const int ZAY = 300004;
struct Edge {
int to,nxt;
};
Edge edge[maxm];int hd[maxn],ecnt;
inline void cont(ci from,ci to) {
Edge &e=edge[++ecnt];
e.to=to;e.nxt=hd[from];hd[from]=ecnt;
}
struct M {
int s,t,an,sum,tk;
inline bool operator<(const M &_others) const {
return this->sum < _others.sum;
}
};
M MU[maxn];
struct W {
int v,num,ans;
inline bool operator<(const W &_others) const {
return this->v < _others.v;
}
};
W w[maxn];
struct C {
int ud,v,tp;
C (int _ud=0,int _v=0,int _tp=0) {ud=_ud,v=_v,tp=_tp;}
};
std::vector<C>cg[maxn];
int n,m;
int deepth[maxn],fa[maxn],LCA[30][maxn],pos[maxn],lft[maxn],rt[maxn];
void t1();
void s1();
void lian();
void baoli();
void zhengjie();
void dfs(ci,ci);
int ask(int,int);
int dfsearch(ci,ci);
void deepfs(ci,ci);
void dfirsts(ci,ci);
inline bool cmp(const W &_a,const W & _b) {
return _a.num < _b.num;
}
int main() {
qr(n);qr(m);
rg int a,b;
for(rg int i=1;i<n;++i) {
a=b=0;qr(a);qr(b);
cont(a,b);cont(b,a);
}
for(rg int i=1;i<=n;++i) {
qr(w[i].v);w[i].num=i;
}
for(rg int i=1;i<=m;++i) {
qr(MU[i].s);qr(MU[i].t);
}
int _num=n%10;
if(_num < 4) baoli();
else if(_num == 4) lian();
else if(_num == 5) s1();
else if(_num == 6) t1();
else zhengjie();
return 0;
}
void dfs(ci u,ci fat) {
deepth[u]=deepth[fa[u]=fat]+1;
LCA[0][u]=fat;
for(rg int i=0;LCA[i][u];++i) {
LCA[i+1][u]=LCA[i][LCA[i][u]];
}
for(rg int i=hd[u];i;i=edge[i].nxt) if(edge[i].to != fat)
dfs(edge[i].to,u);
}
int ask(int x,int y) {
if(deepth[x] < deepth[y]) mswap(x,y);
rg int delta=deepth[x]-deepth[y];
for(rg int i=25;delta;--i) if(delta & (1<<i)) {
x=LCA[i][x],delta^=(1<<i);
}
if(x == y) return x;
for(rg int i=25;i != -1;--i) if(LCA[i][x] != LCA[i][y]) {
x=LCA[i][x],y=LCA[i][y];
}
return LCA[0][x];
}
void baoli() {
dfs(1,0);
for(rg int i=1;i<=m;++i) {
MU[i].an=ask(MU[i].s,MU[i].t);
pos[i]=MU[i].s;
}
std::sort(w+1,w+1+n);
rg int j=1;
for(rg int i=0;i<n;++i) {
while(j <= n) {
if(w[j].v != i) break;
for(rg int k=1;k<=m;++k) if(pos[k] == w[j].num) ++w[j].ans;
++j;
}
for(rg int k=1;k<=m;++k) if(deepth[MU[k].s]+deepth[MU[k].t]-2*deepth[MU[k].an] > i) {
int _d=deepth[MU[k].s]-deepth[MU[k].an];
if(_d > i) {
pos[k]=fa[pos[k]];
}
else {
_d=deepth[MU[k].s]-deepth[MU[k].an]+deepth[MU[k].t]-deepth[MU[k].an]-i-1;
int _t=MU[k].t;
for(rg int h=25;_d;--h) if(_d & (1<<h)) {
_t=LCA[h][_t],_d^=(1<<h);
}
pos[k]=_t;
}
}
else pos[k]=0;
}
while(j <= n) {
for(rg int k=1;k<=m;++k) if(pos[k] == w[j].num) ++w[j].ans;
++j;
}
std::sort(w+1,w+1+n,cmp);
for(rg int i=1;i<n;++i) write(w[i].ans,' ',true);
write(w[n].ans,'\n',true);
}
void lian() {
for(rg int i=1;i<=m;++i) {
if(MU[i].t >= MU[i].s) ++rt[MU[i].s],MU[i].sum=MU[i].t-MU[i].s;
else ++lft[MU[i].s],MU[i].sum=MU[i].s-MU[i].t;
}
std::sort(MU+1,MU+1+m);
std::sort(w+1,w+1+n);
rg int j=0;
for(rg int i=1;i<=n;++i) {
while(j <= m) {
if(MU[j].sum >= w[i].v) break;
if(MU[j].s <= MU[j].t) --rt[MU[j].s];
else --lft[MU[j].s];
++j;
}
int _d=w[i].num-w[i].v;
if(_d > 0) w[i].ans+=rt[_d];
_d=w[i].num+w[i].v;
if(_d <= n) w[i].ans+=lft[_d];
}
std::sort(w+1,w+1+n,cmp);
for(rg int i=1;i<n;++i) write(w[i].ans,' ',true);
write(w[n].ans,'\n',true);
}
void s1() {
deepth[0]=-1;
dfs(1,0);
for(rg int i=1;i<=m;++i) {
++lft[MU[i].t];
}
int _cnt=dfsearch(1,0);
if(!w[1].v) w[1].ans=_cnt;
for(rg int i=1;i<n;++i) write(w[i].ans,' ',true);
write(w[n].ans,'\n',true);
}
int dfsearch(ci u,ci fat) {
rg int _cnt=lft[u];
for(rg int i=hd[u];i;i=edge[i].nxt) if(edge[i].to != fat)
_cnt+=dfsearch(edge[i].to,u);
if(w[u].v == deepth[u]) w[u].ans=_cnt;
return _cnt;
}
void deepfs(ci u,ci fat) {
rg int _c=lft[w[u].v+deepth[u]+ZAY];
lft[deepth[u]+ZAY]+=rt[u];
for(rg int i=hd[u];i;i=edge[i].nxt) if(edge[i].to != fat)
deepfs(edge[i].to,u);
w[u].ans=lft[w[u].v+deepth[u]+ZAY]-_c;
}
void t1() {
deepth[0]=-1;
for(rg int i=1;i<=m;++i) ++rt[MU[i].s];
dfs(1,0);
deepfs(1,0);
for(rg int i=1;i<n;++i) write(w[i].ans,' ',true);
write(w[n].ans,'\n',true);
}
void zhengjie() {
dfs(1,0);
for(rg int i=1;i<=n;++i) {
MU[i].an=ask(MU[i].s,MU[i].t);
MU[i].sum=deepth[MU[i].s]-2*deepth[MU[i].an]+deepth[MU[i].t]+1;
cg[MU[i].s].push_back(C(1,deepth[MU[i].s],1));
cg[MU[i].t].push_back(C(2,deepth[MU[i].t]-MU[i].sum+1+ZAY,1));
cg[MU[i].an].push_back(C(1,deepth[MU[i].s],-1));
cg[fa[MU[i].an]].push_back(C(2,deepth[MU[i].t]-MU[i].sum+1+ZAY,-1));
}
dfirsts(1,0);
for(rg int i=1;i<n;++i) write(w[i].ans,' ',true);
write(w[n].ans,'\n',true);
}
void dfirsts(ci u,ci fat) {
int _temp=lft[deepth[u]+w[u].v]+rt[deepth[u]-w[u].v+ZAY];
rg unsigned int _s=cg[u].size();
for(rg unsigned i=0;i<_s;++i) {
int _ud=cg[u][i].ud;
if(_ud == 1) {
lft[cg[u][i].v]+=cg[u][i].tp;
}
else rt[cg[u][i].v]+=cg[u][i].tp;
}
for(rg int i=hd[u];i;i=edge[i].nxt) if(edge[i].to != fat)
dfirsts(edge[i].to,u);
w[u].ans=lft[deepth[u]+w[u].v]+rt[deepth[u]-w[u].v+ZAY]-_temp;
}