您的位置:首页 > 其它

JZOJ.5286【NOIP2017模拟8.16】花花的森林

2017-08-17 07:59 375 查看

Description

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<ctime>
#define N 200005
#define mo 1000000007
using namespace std;
int head
,next[N*2],to[N*2],va
,up
[30],deep
,x
,y
,n,f
,num,qwq
,sx
,sy
,fa
,ma;
long long ans,dis
,an
;
long long kuai(long long a,int b){
long long d=1;
long long qwq=a;
while (b){
if (b&1) d=d*qwq%mo;
qwq=qwq*qwq%mo;
b>>=1;
}
return d;
}
void add(int u,int v){
num++;
next[num]=head[u];
to[num]=v;
head[u]=num;
num++;
next[num]=head[v];
to[num]=u;
head[v]=num;
}
void updata(int u){
dis[u]=dis[fa[u]]+va[u];
up[u][0]=fa[u];
for (int i=1;i<=25;i++)
up[u][i]=up[up[u][i-1]][i-1];
for (int i=head[u];i;i=next[i]){
int v=to[i];
if (v!=fa[u])
deep[v]=deep[u]+1,fa[v]=u,updata(v);
}
}
int lca(int u,int v){
if (deep[u]<deep[v]) swap(u,v);
for (int i=20;i>=0;i--)
if (deep[v]<=deep[up[u][i]])
u=up[u][i];
if (u==v) return u;
for (int i=20;i>=0;i--)
if (up[u][i]!=up[v][i])
u=up[u][i],v=up[v][i];
return up[u][0];
}
int find(int x){
if (f[x]==x) return x;
f[x]=find(f[x]);
return f[x];
}
void work(int a,int b){
if (deep[a]>deep[b]) swap(a,b);
int f1=find(a),f2=find(b);
f[f2]=f1;
long long qaq=dis[sx[f1]],qvq=dis[sy[f1]],qoq=dis[sx[f2]],qsq=dis[sy[f2]];
int t1=sx[f1],t2=sy[f1],t3=sx[f2],t4=sy[f2];
int l1=lca(sx[f1],sx[f2]),l2=lca(sx[f1],sy[f2]),l3=lca(sy[f1],sx[f2]),l4=lca(sy[f1],sy[f2]),l5=lca(sx[f2],sy[f2]),l6=lca(sx[f1],sy[f1]);
long long tmp3=qaq+qvq-2*dis[l6]+va[l6],tmp2=qsq+qoq-2*dis[l5]+va[l5];
long long tmp1=tmp3;
if (qaq+qoq-2*dis[l1]+va[l1]>tmp1) tmp1=qaq+qoq-2*dis[l1]+va[l1],sx[f1]=t1,sy[f1]=t3;
if (qaq+qsq-2*dis[l2]+va[l2]>tmp1) tmp1=qaq+qsq-2*dis[l2]+va[l2],sx[f1]=t1,sy[f1]=t4;
if (qvq+qoq-2*dis[l3]+va[l3]>tmp1) tmp1=qvq+qoq-2*dis[l3]+va[l3],sx[f1]=t2,sy[f1]=t3;
if (qvq+qsq-2*dis[l4]+va[l4]>tmp1) tmp1=qvq+qsq-2*dis[l4]+va[l4],sx[f1]=t2,sy[f1]=t4;
if (qsq+qoq-2*dis[l5]+va[l5]>tmp1) tmp1=qsq+qoq-2*dis[l5]+va[l5],sx[f1]=t3,sy[f1]=t4;
ans=ans*((tmp1%mo)%mo*(kuai(tmp2,mo-2)%mo)%mo*(kuai(tmp3,mo-2)%mo)%mo)%mo;
an[ma]=ans;
ma--;
}
int main(){
scanf("%d",&n);
for (int i=1;i<=n;i++){
scanf("%d",&va[i]);
f[i]=i;
sx[i]=i;
sy[i]=i;
}
for (int i=1,u,v;i<n;i++){
scanf("%d%d",&u,&v);
x[i]=u;
y[i]=v;
add(u,v);
}
deep[1]=0;
dis[0]=0;
fa[1]=1;
deep[1]=0;
updata(1);
for (int i=1;i<n;i++)
scanf("%d",&qwq[i]);
num=0;
ans=1;
for (int i=1;i<=n;i++)
ans=(ans*(va[i]%mo))%mo;
ma=n;
an[ma]=ans;
ma--;
for (int i=n-1;i>=1;i--){
work(x[qwq[i]],y[qwq[i]]);
}
for (int i=1;i<=n;i++)
printf("%lld\n",an[i]);
return 0;
}


神奇的代码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: