【题目链接】http://www.lydsy.com/JudgeOnline/problem.php?id=1063
【解题思路】切入点是第一个答案不可能大于log3(N),用树链剖分的思想易证不大于log2(N),用满三叉树也不难反证出不大于log3(N),然后就可以将“不便利值”记录进状态了。可参考(http://blog.youkuaiyun.com/thy_asdf/article/details/49451299)(https://www.byvoid.com/blog/noi-2008-design/)
【呆马】
f[i][j][k]表示i节点,子树内最大“不便利值”为j,与其子节点连接了k条边
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<iostream>
#define ll long long
const int N=1e5+1;
using namespace std;
struct st{int to,next;} e[N<<1];
int n,m,cnt,i,x,y,fi[N];
ll mo,f[N][11][3];
void add(int x,int y)
{
e[++cnt].to=y; e[cnt].next=fi[x]; fi[x]=cnt;
e[++cnt].to=x; e[cnt].next=fi[y]; fi[y]=cnt;
}
ll go(ll x)
{
if (x%mo) return x%mo;
if (x) return mo;
return 0;
}
void dp(int x,int fa)
{
bool bo=1;
for (int i=0;i<=10;i++) f[x][i][0]=1;
for (int y,i=fi[x];i;i=e[i].next)
if (e[i].to!=fa)
{
bo=0;
dp(y=e[i].to,x);
for (int j=0;j<=10;j++)
{
ll p=j==0?0:f[y][j-1][0]+f[y][j-1][1]+f[y][j-1][2];
ll q=f[y][j][0]+f[y][j][1];
f[x][j][2]=go(f[x][j][2]*p+f[x][j][1]*q);
f[x][j][1]=go(f[x][j][1]*p+f[x][j][0]*q);
f[x][j][0]=go(f[x][j][0]*p);
}
}
}
int main()
{
scanf("%d%d%lld",&n,&m,&mo);
if (m!=n-1)
{
printf("-1\n-1");
return 0;
}
for (i=1;i<n;i++)
{
scanf("%d%d\n",&x,&y);
add(x,y);
}
dp(1,0);
for (i=0;i<=10;i++)
if (f[1][i][0]+f[1][i][1]+f[1][i][2])
{
printf("%d\n%lld",i,(f[1][i][0]+f[1][i][1]+f[1][i][2])%mo);
return 0;
}
}