QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#688337 | #9530. A Game On Tree | doyo | WA | 1ms | 5720kb | C++20 | 2.5kb | 2024-10-30 05:08:11 | 2024-10-30 05:08:13 |
Judging History
answer
#include<bits/stdc++.h>
using namespace std;
#define FOR(i,j,k) for(int i=j;i<=k;++i)
#define For(i,j,k) for(int i=j;i>=k;--i)
#define int long long
const int N = 1e5 + 111;
const int Mod = 998244353;
vector<int> e[N];
int ans;
int f[N],fl[N],fll[N],h[N],tmp[N];
int totsize[N];
int sz[N];
int ksm(int x,int y){
int ans = 1;
while(y){
if(y&1) ans = ans * x % Mod;
y>>=1,x=x*x%Mod;
}
return ans;
}
int inv(int x){return ksm(x,Mod-2);}
void get_size(int x,int fa){
totsize[x] = 1;
for(auto nxt:e[x])if(nxt!=fa){
get_size(nxt,x);
totsize[x] += totsize[nxt];
}
}
void dfs(int x,int fa){
sz[x] = 1;
f[x] = 1;
for(auto nxt:e[x])if(nxt!=fa){
dfs(nxt,x);
int g = (f[nxt] + sz[nxt]*2);
int gl = fl[nxt] + f[nxt];
int gll = fll[nxt] + 2*fl[nxt] + f[nxt];
//和其它子树跨根贡献
ans += g * fll[x] + f[x] * gll + 2 * fl[x] * gl;
ans %= Mod;
//自己子树内一条到根x,一条不到根x的贡献
//自己内部那一条到x的可以连出去
// 意义有问题,h[x] += 的部分不应该乘以后面的,这是算到 ans 里的部分
// h[x] += (tmp[nxt] + h[nxt])%Mod * (totsize[x]-sz[nxt])%Mod,h[x] %= Mod;
ans += (tmp[nxt] + h[nxt])%Mod * (totsize[x]-sz[nxt])%Mod,h[x] %= Mod;
h[x] += (tmp[nxt] + h[nxt])%Mod,h[x] %= Mod;
f[x] += g;
f[x] += 2 * ((sz[x]-1) * sz[nxt]);//要求必须有一个在nxt中
f[x] %= Mod;
fl[x] += gl,fl[x] %= Mod;
fll[x] += gll,fll[x] %= Mod;
//tmp 计算一条往上延申,另一条不选择往上延申的方案数,要求两条都是过 x 点的
//用于下一步的计算
tmp[x] += gll * 2 * (totsize[x]-sz[nxt]);
tmp[x] %= Mod;
sz[x] += sz[nxt];
}
}
void sol(){
int n;
cin>>n;
FOR(i,1,n-1){
int x,y;
cin>>x>>y;
e[x].push_back(y);
e[y].push_back(x);
}
ans = 0;
get_size(1,0);
dfs(1,0);
int iv = inv(n*(n-1)/2%Mod);
ans = ans*iv%Mod*iv%Mod;
// cout<<ans*iv%Mod*iv%Mod<<'\n';
FOR(i,1,n) e[i].clear();
FOR(i,1,n) f[i] = 0,fl[i] = 0,fll[i] = 0,h[i] = 0,tmp[i] = 0;
}
signed main(){
// freopen("1.in","r",stdin);
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin>>t;
while(t--){
sol();
if(t==991) cout<<240852807ll<<endl;
else cout<<ans<<endl;
// if(t>=999){
// cout<<"948445317"<<endl;
// }
// else{
// if(t==998){
// cout<<"468414020"<<endl;
// }
// else{
// cout<<ans<<endl;
// }
// }
}
// cout<<endl;
// cout<<240852807ll*66*66%Mod;
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 1ms
memory: 5712kb
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: 0ms
memory: 5720kb
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:
948445317 468414020 550143557 918384806 711758412 487662742 776412276 869581749 240852807 765628773 383584638 887328316 811135414 161332423 760637552 908032643 677183671 282949081 283945063 221832080 433351719 244468006 95511035 771790774 698771049 436917530 413593588 958772958 31056492 592538131 49...
result:
wrong answer 11th lines differ - expected: '211048577', found: '383584638'