タイトル説明
小さなC学生はジョギングは非常に興味深いと思い、ゲームの「実行中の愛の日々」というセクションを作ることにしました。「愛が実行されている毎日は、」タスクのパンチを完了するために、時間に毎日ライン上の選手を必要とするゲームを開発することです。
ゲームマップは、11個のノードNNNおよびn-1N-1N-1ツリーエッジストリップを含むと考えることができ、各エッジは、2つのノードを接続し、任意の2つのノードの存在は、各パスに到達することができます。111からNNNまでの連続した正の整数のツリーノード番号。
ある選手は、MMM sis_isi、エンドポイントtit_itiのための出発点選手のIII。一日の後にパンチタスクを開始するには、最初の000秒での開始点から同時にすべてのプレイヤーは、そのプレイヤーが完了しても、フィニッシュラインへの最短経路に沿って、彼自身の端に向かって第2レート側、中断のないRANを実行するときパンチタスク。(マップが木なので、みんなのパスが一意になるように)
各ノードは、観察者を配置しているので、小さなC、活動ゲームを疑問。ノードオブザーバのJJJは、プレイヤーが最初のプレイヤーが第2の点JJJ wjw_jwjも取っ処理に達した場合に限り、オブザーバーを観察することができ、最初のwjw_jwj秒を選択するためのプレーヤーを観察します。各小さなCオブザーバーはどのように多くの人々を観察します知りたいですか?
注:私たちは、プレイヤーが自分の最後に到達した後、プレイヤーがゲームを終了することを信じて、彼は観察者に観察される前に、いくつかの時間を待つことができませんでした。ノードJJJエンドとしてプレイヤーのために、次のとおりです。彼は秒前最初wjw_jwjの終わりに達した場合、その後、プレイヤーはオブザーバーJJJノードを観察することはできません。彼はwjw_jwj秒の終わりに到達するために発生した場合、ノードJJJオブザーバは選手を観察することができます。
入力形式
最初の行は二つの整数NNNとMMMを持っています。ツリーのノードの数もオブザーバーの数をNNN表しますが、ここで、MMMは選手の数を表します。
次に、n 1N-1N-1ライン毎、及び二つの整数UUUをVVVは、UUUは、エッジがあるノードVVVにノードを表します。
最初の整数はJJJのwjw_jwj、タイミングノードJJJオブザーバ表示され、前記次のラインNNN整数。
二つの整数sis_isi、およびtit_itiの次MMMラインは、プレイヤーの開始点と終了点を表します。
全てのデータに対して、1≤si確実にするために、ti≤n、0≤wj≤n1\当量S_I、T_I \当量のN、0 \当量w_j \当量n1≤si、TI≤n、0≤wj≤n 。
出力フォーマット
NNN整数出力ライン111は、最初のノードは、整数JJJのJJJのオブザーバーはどのように多くの人々を観察することができ表します。
[解説]羅区1600は毎日愛を実行しています
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int N=6e5+10;
inline int read(){
int x=0; char c=getchar();
while(c<'0'||c>'9')c=getchar();
while('0'<=c&&c<='9'){ x=(x<<3)+(x<<1)+(c^48); c=getchar(); }
return x;
}
int nxt[N<<1],head[N],go[N<<1],tot;
inline void add(int u,int v){nxt[++tot]=head[u],head[u]=tot,go[tot]=v,nxt[++tot]=head[v],head[v]=tot,go[tot]=u;}
int n,m,w[N],f[N][17];
struct node{
int x,lca,op;
};
vector<node>a[N];
int dep[N];
void deal(int u,int fa){
dep[u]=dep[fa]+1;
for(int i=0;i<16;i++)f[u][i+1]=f[f[u][i]][i];
for(int i=head[u];i;i=nxt[i]){
int v=go[i];
if(v==fa)continue;
f[v][0]=u;
deal(v,u);
}
}
#define _ 10000
inline int LCA(int x,int y){
if(dep[x]<dep[y])swap(x,y);
for(int i=16;i>=0;i--)if(dep[f[x][i]]>=dep[y])x=f[x][i];
if(x==y)return x;
for(int i=16;i>=0;i--)if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
return f[x][0];
}
int cnt1[N],cnt2[N],ans[N];
vector<int>del1[N],del2[N];
void dfs(int u,int fa){
int x=cnt1[_+dep[u]+w[u]],y=cnt2[_+w[u]-dep[u]];
for(int i=head[u];i;i=nxt[i]){
int v=go[i];
if(v==fa)continue;
dfs(v,u);
}
for(int i=0;i<a[u].size();i++){
int x=a[u][i].x,lca=a[u][i].lca;
if(a[u][i].op){
cnt1[_+dep[u]]++;
del1[lca].push_back(dep[u]);
}
else {
cnt2[_+dep[x]-2*dep[lca]]++;
del2[lca].push_back(dep[x]-2*dep[lca]);
}
}
for(int i=0;i<del1[u].size();i++)cnt1[_+del1[u][i]]--;
ans[u]=cnt1[_+dep[u]+w[u]]-x+cnt2[_+w[u]-dep[u]]-y;
for(int i=0;i<del2[u].size();i++)cnt2[_+del2[u][i]]--;
}
signed main(){
n=read(),m=read();
for(int i=1;i<n;i++)add(read(),read());
deal(1,1);
for(int i=1;i<=n;i++)w[i]=read();
for(int i=1,x,y,z;i<=m;i++){
x=read(),y=read();
z=LCA(x,y);
a[x].push_back((node){y,z,1});
a[y].push_back((node){x,z,0});
}
dfs(1,0);
for(int i=1;i<=n;i++)printf("%d ",ans[i]);
printf("\n");
return 0;
}