QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#685072 | #9530. A Game On Tree | SSAABBEERR | WA | 2ms | 9976kb | C++20 | 6.2kb | 2024-10-28 17:26:37 | 2024-10-28 17:26:37 |
Judging History
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+++'