1 条题解

  • 1
    @ 2023-07-12 15:20:28

    std:

    #include<bits/stdc++.h>
    #define int long long
    #define P 1226999999
    using namespace std;
    int Pow(int A,int B){
        int res=1;
        while(B){
            if(B&1){
                res=res*A%P;
            }
            A=A*A%P;
            B>>=1;
        }
        return res;
    }
    int n,m;
    int tot,head[100005],nxt[200005],to[200005];
    int col[100005];
    int sum[100005],sqs[100005],ssz[100005],sqz[100005];
    int dp[100005];
    int siz[100005],father[100005],top[100005],depth[100005],dist[100005];
    int val1[100005];//Vx^2+Vy^2+2VxVy
    int val2[100005];//x contain y or y contain x
    int val3[100005];//different subtree
    struct _Query_{
        int id;
        int v,w;
    };
    vector<_Query_>Q[100005];
    int ans[100005];
    void AddEdge(int u,int v){
        to[++tot]=v;
        nxt[tot]=head[u];
        head[u]=tot;
    }
    void dfs1(int p,int fa){
        siz[p]=1;
        sum[p]=0;
        ssz[p]=0;
        sqz[p]=0;
        ssz[p]=0;
        father[p]=fa;
        depth[p]=depth[fa]+1;
        dist[p]=dist[fa]+col[p];
        for(int i=head[p];i;i=nxt[i]){
            if(to[i]!=fa){
                dfs1(to[i],p);
                siz[p]+=siz[to[i]];
                sum[p]=(sum[p]+sum[to[i]])%P;
                sqs[p]=(sqs[p]+sqs[to[i]])%P;
                ssz[p]=(ssz[p]+ssz[to[i]])%P;
                sqz[p]=(sqz[p]+sqz[to[i]])%P;
            }
        }
        sum[p]=(sum[p]+col[p])%P;
        sqs[p]=(sqs[p]+col[p]*col[p]%P)%P;
        ssz[p]=(ssz[p]+sum[p]*(siz[p]-1)%P)%P;
        sqz[p]=(sqz[p]+sum[p]*sum[p]%P*(siz[p]-1)%P)%P;
        dp[p]=(sum[p]+dist[p]-col[p]+P)%P;
    }
    int smp[100005],sqp[100005];
    int smk[100005],sqk[100005];
    void dfs2(int p,int fa){
        smp[p]=dp[p];
        sqp[p]=dp[p]*dp[p]%P;
        for(int i=head[p];i;i=nxt[i]){
            if(to[i]!=fa){
                dfs2(to[i],p);
                smp[p]=(smp[p]+smp[to[i]])%P;
                sqp[p]=(sqp[p]+sqp[to[i]])%P;
            }
        }
    }
    void dfs3(int p,int fa){
        smk[p]=0;
        sqk[p]=0;
        for(int i=head[p];i;i=nxt[i]){
            if(to[i]!=fa){
                dfs3(to[i],p);
                smk[p]=(smk[p]+(2*smp[to[i]]-(2*dist[p]-col[p])*siz[to[i]]%P+P)%P*(siz[p]-siz[to[i]]-1)%P+P)%P;
                //sum[p]*D
                
                sqk[p]=(sqk[p]+2*sqp[to[i]]*(siz[p]-siz[to[i]]-1)%P+2*smp[to[i]]%P*(smp[p]-smp[to[i]]-dp[p])%P)%P;
                //(dp[u]+dp[v])^2
                
                sqk[p]=(sqk[p]-4*smp[to[i]]%P*(2*dist[p]-col[p])%P*(siz[p]-siz[to[i]]-1)%P+P)%P;
                //-2*(dp[u]+dp[v])*(2*dist[p]-col[p])
                
                sqk[p]=(sqk[p]+(2*dist[p]-col[p])%P*(2*dist[p]-col[p])%P*siz[to[i]]%P*(siz[p]-siz[to[i]]-1)%P)%P;
                //(2*dist[p]-col[p])^2
                
                smk[p]=(smk[p]+smk[to[i]])%P;
                sqk[p]=(sqk[p]+sqk[to[i]])%P;
            }
        }
        
        val1[p]=((sum[p]*sum[p]%P-sqs[p]+P)%P*2%P+sqs[p]*(siz[p]-1)%P*2%P)%P;
        
        val2[p]=(ssz[p]*sum[p]%P-sqz[p]+P)%P*2%P;
            
        val3[p]=(smk[p]*sum[p]%P-sqk[p]+P)%P;
    
        for(int i=0;i<Q[p].size();i++){
            ans[Q[p][i].id]=(((val1[p]+(val2[p]+val3[p])*col[Q[p][i].v]%P)%P+P)%P*Pow(siz[p]%P*(siz[p]-1)%P,P-2)%P+Pow(Q[p][i].w+col[Q[p][i].v],3))%P;
        }
    }
    signed main(){
        int u,v,w;
        scanf("%lld%lld",&n,&m);
        for(int i=1;i<=n;i++){
            scanf("%lld",col+i);
        }
        for(int i=1;i<n;i++){
            scanf("%lld%lld",&u,&v);
            AddEdge(u,v);
            AddEdge(v,u);
        }
        for(int i=1;i<=m;i++){
            scanf("%lld%lld%lld",&u,&v,&w);
            Q[v].push_back((_Query_){i,u,w});
        }
        dfs1(1,0);
        dfs2(1,0);
        dfs3(1,0);
        for(int i=1;i<=m;i++){
            printf("%lld\n",ans[i]);
        }
    }
    
    
  • 1

信息

ID
1035
难度
1919810
分类
树结构 点击显示
标签
递交数
10
已通过
1
通过率
10%
上传者