Title Description
Description
Input
Output
Sample Input
3
1 2
1 3
Sample Output
2
Explanation
only if the communication blocks or the entire tree is only one little Yao lose, win Yao small remaining cases.
Data Constraint
answer
A communication block losing the upper hand, if and only if a diameter at the midpoint of the diameter and length is odd
prove:
If the length is odd and not at the midpoint, the upper hand can be moved to the midpoint, the other can be moved to shift no matter how the diameter of the point of symmetry
If the length of the case is even, the upper hand can be moved to the midpoint far as the moving distance of the opponent next> 1 can not be moved to another midpoint, the odd similar
Set \ (F [i] [j] \) represents the root to the point i, the maximum depth is the number j of the subtree, and finally combined at a
Clearly related to the depth dp is a long chain split, the \ (f [u] [1 \ sim x] \) and \ (F [V] [. 1 \ SIM Y] \) ( \ (X> Y \) ) merge, for \ (1 \ sim y \) portion violence were combined, then \ (y + 1 \) at the number on the back of a reward by suffix numerals
Maintenance can be directly transferred when \ (f \) suffix value, the final answer is calculated using the total - is not legitimate, then a similar dp can calculate the number of illegal
至于状态的保存,因为一条链的状态数=链长,所以可以按深度从上到下存到树上,表示深度1,2,3...时的\(f\),在上传重儿子时也只需考虑新加的那一个点
code
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define mod 998244353
#define file
using namespace std;
int a[2000001][2];
int b[1000002];
int c[1000002];
int ls[1000001];
int dp[1000001];
int fa[1000001];
bool bz[1000001];
int d[1000001];
int I[1000001];
int nx[1000001];
long long g[1000001];
long long f[1000001];
long long F[1000001];
int st[1000001];
long long Ans[1000001][3];
long long Ans2[1000001];
int n,i,j,k,l,len,h,t,tot;
long long ans;
void New(int x,int y)
{
++len;
a[len][0]=y;
a[len][1]=ls[x];
ls[x]=len;
}
void bfs()
{
int i,mx,mx2;
h=0;t=1;
d[1]=1;
bz[1]=1;
while (h<t)
{
for (i=ls[d[++h]]; i; i=a[i][1])
if (!bz[a[i][0]])
{
fa[a[i][0]]=d[h];
bz[a[i][0]]=1;
d[++t]=a[i][0];
}
}
fd(l,t,1)
{
mx=0;mx2=-1;
g[d[l]]=1;
for (i=ls[d[l]]; i; i=a[i][1])
if (a[i][0]!=fa[d[l]])
{
g[d[l]]=g[d[l]]*(g[a[i][0]]+1)%mod;
if (dp[a[i][0]]>mx)
mx=dp[a[i][0]],mx2=a[i][0];
}
nx[d[l]]=mx2;
dp[d[l]]=mx+1;
}
ans=g[1];
}
void down(int t)
{
f[t]=f[t]*F[t]%mod;
if (nx[t]!=-1)
F[nx[t]]=F[nx[t]]*F[t]%mod;
F[t]=1;
}
void dfs(int st)
{
int T,i,j,k,l;
long long sum,s1,s2;
t=1;
d[1]=st;
while (t)
{
T=d[t];
if (nx[T]!=-1 && bz[T])
{
bz[T]=0;
d[++t]=nx[T];
}
else
if (I[T])
{
if (a[I[T]][0]==fa[T] || a[I[T]][0]==nx[T])
I[T]=a[I[T]][1];
else
{
d[++t]=a[I[T]][0];
I[T]=a[I[T]][1];
}
}
else
{
if (fa[T]!=1)
{
if (nx[fa[T]]==T)
f[fa[T]]=(f[T]*F[T]+1)%mod;
else
{
tot=0;
i=fa[T];j=T;
while (j!=-1)
{
++tot;
b[tot]=i;c[tot+1]=j;
down(i);down(j);
i=nx[i];j=nx[j];
}
b[++tot]=i;
down(i);
sum=s1=s2=0;
if (nx[i]!=-1)
{
s1=f[nx[i]]*F[nx[i]]%mod;
sum=f[nx[i]]*F[nx[i]]%mod*f[T]%mod;
F[nx[i]]=F[nx[i]]*(f[T]+1)%mod;
}
fd(i,tot,2)
{
sum=(sum+(f[b[1]]-s1)*(f[c[2]]+1-s2)-(f[b[1]]-f[b[i]])*(f[c[2]]+1-f[c[i]])-(f[b[i]]-s1))%mod;
s1=f[b[i]];s2=f[c[i]];
f[b[i]]=(f[b[i]]+sum)%mod;
}
f[b[1]]=(f[b[1]]+sum)%mod;
}
}
--t;
}
}
}
int main()
{
freopen("tree.in","r",stdin);
#ifdef file
freopen("tree.out","w",stdout);
#endif
scanf("%d",&n);
Ans2[1]=Ans[1][0]=f[1]=F[1]=1;
fo(i,2,n)
{
scanf("%d%d",&j,&k);
Ans2[i]=Ans[i][0]=f[i]=F[i]=1;
New(j,k);
New(k,j);
}
fo(i,1,n) I[i]=ls[i];
bfs();
for (i=ls[1]; i; i=a[i][1])
dfs(a[i][0]);
for (i=ls[1]; i; i=a[i][1])
{
j=a[i][0];
tot=1;
while (j!=-1)
{
down(j);
b[++tot]=j;
j=nx[j];
}
b[tot+1]=0;
Ans2[tot+1]=Ans2[tot+1]*(f[b[2]]+1)%mod;
fo(j,2,tot)
{
Ans[j][2]=(Ans[j][2]*(f[b[2]]-f[b[j+1]]+1))%mod;
fd(k,1,0)
{
Ans[j][k+1]=(Ans[j][k+1]+Ans[j][k]*(f[b[j]]-f[b[j+1]]))%mod;
Ans[j][k]=Ans[j][k]*(f[b[2]]-f[b[j]]+1)%mod;
}
}
}
--ans;
fo(i,2,n)
{
ans=(ans-Ans[i][2]*Ans2[i])%mod;
Ans2[i+1]=Ans2[i+1]*Ans2[i]%mod;
}
printf("%lld\n",(ans+mod)%mod);
}