比赛 2025.3.29 评测结果 AWWWWWWWWWAAAWAAAWWWWWWWW
题目名称 硝华流焰 最终得分 28
用户昵称 djyqjy 运行时间 1.936 s
代码语言 C++ 内存使用 18.43 MiB
提交时间 2025-03-29 11:58:43
显示代码纯文本
#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int re()
{
    int f=1,num=0;
    char c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
    while(c>='0'&&c<='9') num=num*10+c-'0',c=getchar();
    return num*f;
}
const int N=100010,MOD=1e9+7;
struct edge
{
    int ver[2*N],edge[2*N],nxt[2*N],hd[N];
    int jsq=1;
    inline void add_edge(int x,int y,int z)
    {
        ver[++jsq]=y;
        edge[jsq]=z;
        nxt[jsq]=hd[x];
        hd[x]=jsq;
        ver[++jsq]=x;
        edge[jsq]=z;
        nxt[jsq]=hd[y];
        hd[y]=jsq;
        return;
    }
}edge;
int n,rt,ans,ls;
int a[N],sz[N],maxs[N],mark[N],dp[N][8],dp2[N][8],tt[8],tt2[8];
void get_root(int x,int fa,int t)
{
    sz[x]=1;maxs[x]=0;
    for(int i=edge.hd[x];i;i=edge.nxt[i])
    {
        int y=edge.ver[i];
        if(y==fa||mark[y]) continue;
        get_root(y,x,t);
        sz[x]+=sz[y];maxs[x]=max(maxs[x],sz[y]);
    }
    maxs[x]=max(maxs[x],t-sz[x]);
    if(rt==0||maxs[x]<maxs[rt]) rt=x;
    return;
}
void get_col(int x,int fa)
{
    dp2[x][1<<a[x]]=1;
    for(int i=edge.hd[x];i;i=edge.nxt[i])
    {
        int y=edge.ver[i];
        if(y==fa||mark[y]) continue;
        get_col(y,x);
        for(int j=0;j<8;j++)
        {
            dp[x][j|(1<<a[x])]+=dp[y][j]+dp2[y][j]*edge.edge[i];
            dp2[x][j|(1<<a[x])]+=dp2[y][j];
        }
    }
    return;
}
void clear(int x,int fa)
{
    for(int i=edge.hd[x];i;i=edge.nxt[i])
    {
        int y=edge.ver[i];
        if(y==fa||mark[y]) continue;
        for(int j=0;j<8;j++) dp[x][j]=dp2[x][j]=0;
        clear(y,x);
    }
}
void solve(int x)
{
    mark[x]=1;
    for(int i=edge.hd[x];i;i=edge.nxt[i])
    {
        int y=edge.ver[i];
        if(mark[y]) continue;
        get_col(y,x);
        for(int j=0;j<8;j++) tt[j]=tt2[j]=0;
        for(int j=0;j<8;j++)
        {
            tt[j|(1<<a[x])]+=dp[y][j]+dp2[y][j]*edge.edge[i];
            tt2[j|(1<<a[x])]+=dp2[y][j];
        }
        for(int l=0;l<8;l++) for(int j=0;j<8;j++)
            if((l|j)==7) ans=(ans+dp[x][l]*tt2[j]+dp2[x][l]*tt[j])%MOD;
        for(int j=0;j<8;j++)
        {
            dp[x][j|(1<<a[x])]+=dp[y][j]+dp2[y][j]*edge.edge[i];
            dp2[x][j|(1<<a[x])]+=dp2[y][j];
        }
    }
    clear(x,0);
    for(int i=edge.hd[x];i;i=edge.nxt[i])
    {
        int y=edge.ver[i];
        if(mark[y]) continue;
        rt=0;
        get_root(y,0,sz[y]);
        solve(rt);
    }
    return;
}
signed main()
{
    freopen("blossom.in","r",stdin);
    freopen("blossom.out","w",stdout);
    n=re();
    for(int i=1;i<=n;i++) a[i]=re();
    for(int i=1,x,y,z;i<n;i++) x=re(),y=re(),z=re(),edge.add_edge(x,y,z);
    get_root(1,0,n);
    solve(rt);
    printf("%lld",ans%MOD);
    return 0;
}