QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#685072#9530. A Game On TreeSSAABBEERRWA 2ms9976kbC++206.2kb2024-10-28 17:26:372024-10-28 17:26:37

Judging History

This is the latest submission verdict.

  • [2024-10-28 17:26:37]
  • Judged
  • Verdict: WA
  • Time: 2ms
  • Memory: 9976kb
  • [2024-10-28 17:26:37]
  • Submitted

answer

#pragma GCC optimize(3)  //O2优化开启
#include<bits/stdc++.h>
using namespace std;
#define int long long
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
const int mod=998244353;
const int MX=0x3f3f3f3f3f3f3f3f; 

const int inf=10000000;
const int maxn=100010;
const int inv2=499122177;
int n,m;
struct node{int v,dis,nxt;}E[maxn<<1];
int tot,head[maxn];
int maxp[maxn],sz[maxn],dis[maxn];
int vis[maxn];
int depth[maxn];
int dp[maxn];

int sum,rt;
int ans;

int kuai(int a,int b){

    int ans=1;
    while(b){

        if(b&1)ans=ans*a%mod;
        b>>=1;
        a=a*a%mod;

    }
    return ans%mod;

}


void add(int u,int v,int dis)           //建边
{
    E[++tot].nxt=head[u];
    E[tot].v=v;
    E[tot].dis=dis;
    head[u]=tot;
}

void getrt(int u,int pa)            //得到每个数的树根
{
    sz[u]=1; maxp[u]=0;
    for(int i=head[u];i;i=E[i].nxt)
    {
        int v=E[i].v;
        if(v==pa||vis[v]) continue;
        getrt(v,u);
        sz[u]+=sz[v];
        maxp[u]=max(maxp[u],sz[v]);
    }
    maxp[u]=max(maxp[u],sum-sz[u]);
    if(maxp[u]<maxp[rt]) rt=u;
}

vector<array<int,3>>ve;
int suv=0;          //a*a
        
int sux=0;            //2*a

int szu=0;          //len的个数

int op=0;

int idx;

void dfs(int u,int fa){

    depth[u]=++idx;

    dp[u]=1;

    for(int i=head[u];i;i=E[i].nxt){

        int v=E[i].v;

        if(v==fa)continue;

        dfs(v,u);

        dp[u]+=dp[v];

    }

}
int query(int x,int y){

    if(depth[x]<depth[y]){
        return n-dp[y];
    }
    else{
        return dp[x];
    }

}

//对分块的子树进行dfs遍历,求出每个以根为边节点或者经过该节点的路径(此处要求出每个点到分块根节点的权值)
int getdis(int u,int fa,int len){        
    // cout<<u<<"+++\n";
    int cnt=1;

    int szz=1;

    for(int i=head[u];i;i=E[i].nxt){

        int v=E[i].v;

        if(v==fa)continue;

        if(vis[v]){
            cout<<v<<"+++\n";
            int x=query(v,u);

            szz=(szz+2*cnt*x%mod)%mod;

            cnt+=x;

            continue;
        }

        int x=getdis(v,u,len+1);

        szz=(szz+2*cnt*x%mod)%mod;

        cnt+=x;

    }

    int summ=len*len%mod*szz%mod;

    // dan=(dan+len*len%mod*szz%mod)%mod;

    int suxx=2*len%mod*szz%mod;

    ve.push_back({summ,suxx,szz});

    ans=(ans+(len*len%mod*szu%mod+suv+sux*len%mod)%mod*szz%mod)%mod;

    // if(u==1){
    //     cout<<len<<" "<<suv<<" "<<sux<<" "<<szu<<" "<<szz<<"++\n";
    // }

    return cnt;

}

void calc(int u){           //对每一颗根为u的子树进行求解
    // cout<<u<<"++++\n";
    suv=sux=0;
    szu=0;
    int ou=1;
    int sumtr=1;
    int sumop=0;
    vector<array<int,3>>acm;
    for(int i=head[u];i;i=E[i].nxt){

        int v=E[i].v;

        if(vis[v]){
            
            int xx=query(v,u);

            sumtr=(sumtr+xx)%mod;

            sumop=(sumop+xx*(xx-1)/2)%mod;

            continue;
        }

        int km=getdis(v,u,1);

        // if(u==2){
        //     cout<<v<<"---\n";
        // }

        int hh=0;

        for(auto [x,y,z]:ve){

            suv=(suv+x)%mod;

            sux=(sux+y)%mod;

            szu=(szu+z)%mod;

            hh=(hh+x)%mod;

        }

        acm.push_back({hh,km,v});

        sumop=(sumop+km*(km-1)*inv2)%mod;

        sumtr=(sumtr+km)%mod;

        // cout<<suv<<" "<<sux<<" "<<szu<<"++++\n";

        // if(u==2){
        //     cout<<ans<<"+++\n";

        // }

        ou=ou+ve[i].size();
        ou%=mod;
        ve.clear();

        // if(u==2){
        //     cout<<ans<<"+++\n";
        //     // cout<<ans<<" "<<suv<<" "<<sux<<" "<<szu<<"++++\n";
        // }

    }

    // if(u==2)cout<<sumop<<" "<<sumtr<<"***\n";

    for(auto [i,j,v]:acm){
        // if(u==2)cout<<i<<" "<<j<<"++++\n";
        int c2=(sumop-(j*(j-1+mod)%mod*inv2)%mod+mod)%mod;

        int yao=(sumtr-j+mod)%mod;

        yao=((yao-1+mod)%mod*yao%mod*inv2)%mod;

        yao=(yao-c2+mod)%mod;

        yao=(yao*2+1)%mod;

        // if(u==2)cout<<yao<<"++\n";

        ans=(ans+i%mod*yao%mod)%mod;



        // if(u==2)cout<<yao<<":::"<<i<<"----\n";

    }

    // if(u==2){
    //     cout<<ans<<"+++\n";
    // }

}

void solvedfs(int u){               //此处进行分块

    vis[u]=1;
    calc(u);

    for(int i=head[u];i;i=E[i].nxt){

        int v=E[i].v;

        if(vis[v])continue;

        sum=sz[v];  maxp[rt=0]=inf;

        getrt(v,0);  solvedfs(rt);

    }

}


void icealsoheat(){

    cin>>n;
    ans=0;
    tot=0;
    idx=0;
    for(int i=1;i<=n;i++)head[i]=0,maxp[i]=0,vis[i]=0;

    for(int i=1;i<n;i++){
        int l,r;
        cin>>l>>r;
        add(l,r,0);
        add(r,l,0);

    }

    dfs(1,0);

    maxp[rt]=sum=n;

    getrt(1,0);
    solvedfs(rt);
    int xx=n*(n-1)/2;
    xx=kuai(xx,mod-2);
    xx=xx*xx%mod;

    ans=ans*xx%mod;

    cout<<ans<<"\n";

}
signed main(){
    ios::sync_with_stdio(false);          //int128不能用快读!!!!!!
    cin.tie();
    cout.tie();
    int _yq;
    _yq=1;
    cin>>_yq;
    // cout<<(918384806ll*100)%mod<<"***\n";
    // yu();
    // cout<<kuai(2,mod-2)<<"***";
    while(_yq--){
        icealsoheat();
    }
}
//
//⠀⠀⠀             ⠀⢸⣿⣿⣿⠀⣼⣿⣿⣦⡀
//⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⠀⠀⠀ ⠀⢸⣿⣿⡟⢰⣿⣿⣿⠟⠁
//⠀⠀⠀⠀⠀⠀⠀⢰⣿⠿⢿⣦⣀⠀⠘⠛⠛⠃⠸⠿⠟⣫⣴⣶⣾⡆
//⠀⠀⠀⠀⠀⠀⠀⠸⣿⡀⠀⠉⢿⣦⡀⠀⠀⠀⠀⠀⠀ ⠛⠿⠿⣿⠃
//⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣦⠀⠀⠹⣿⣶⡾⠛⠛⢷⣦⣄⠀
//⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣧⠀⠀⠈⠉⣀⡀⠀ ⠀⠙⢿⡇
//⠀⠀⠀⠀⠀⠀⢀⣠⣴⡿⠟⠋⠀⠀⢠⣾⠟⠃⠀⠀⠀⢸⣿⡆
//⠀⠀⠀⢀⣠⣶⡿⠛⠉⠀⠀⠀⠀⠀⣾⡇⠀⠀⠀⠀⠀⢸⣿⠇
//⢀⣠⣾⠿⠛⠁⠀⠀⠀⠀⠀⠀⠀⢀⣼⣧⣀⠀⠀⠀⢀⣼⠇
//⠈⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⡿⠋⠙⠛⠛⠛⠛⠛⠁
//⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣾⡿⠋⠀
//⠀⠀⠀⠀⠀⠀⠀⠀⢾⠿⠋⠀
//

详细

Test #1:

score: 100
Accepted
time: 1ms
memory: 9976kb

input:

2
3
1 2
2 3
5
1 2
1 5
3 2
4 2

output:

443664158
918384806

result:

ok 2 lines

Test #2:

score: -100
Wrong Answer
time: 2ms
memory: 9692kb

input:

1000
7
3 6
4 3
5 3
2 6
1 4
7 1
12
5 7
10 7
2 10
11 2
1 7
8 1
4 2
9 11
6 9
12 11
3 5
6
2 5
1 2
4 5
6 4
3 6
5
2 5
1 5
4 5
3 2
8
1 8
2 8
4 2
6 1
5 6
7 6
3 8
8
3 8
7 3
4 8
6 4
2 7
5 2
1 4
4
3 1
4 3
2 1
6
5 1
6 1
2 5
3 5
4 2
12
8 11
5 11
12 8
3 12
6 12
2 3
4 6
10 11
1 5
9 5
7 5
9
6 1
7 6
4 7
8 7
5 4
9 6
...

output:

4+++
3+++
948445317
2+++
2+++
7+++
7+++
468414020
5+++
550143557
1+++
918384806
8+++
711758412
3+++
3+++
487662742
776412276
5+++
869581749
12+++
12+++
8+++
240852807
6+++
6+++
765628773
1+++
2+++
211048577
9+++
887328316
1+++
6+++
1+++
890334966
5+++
940494682
5+++
5+++
5+++
760637552
4+++
4+++
908...

result:

wrong answer 1st lines differ - expected: '948445317', found: '4+++'