【JZOJ 4816】【NOIP2016提高组 五校联考4】label

Description

这里写图片描述
这里写图片描述

Analysis

首先,40分的dp很容易想,设f[i][j]表示给i的子树做完,给i赋j的方案数。

f[i][j]=vson(i)f[v][x](|xj|k)

随便乱搞些东西就有60~80分了。
然后有一个很显然却容易忽视的性质:f[i]是对称的。
而且中间有一大段的值是一样的!
可以证明(思考一下),因为 k<=100,所以 dp 值一端最多只有 99*100 个不同的。
所以只需要记录这么多个DP值,可以快速的算出来。

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,b,a) for(int i=b;i>=a;i--)
#define efo(i,v) for(int i=last[v];i;i=next[i])
using namespace std;
typedef long long ll;
const int N=110,M=10010,mo=1e9+7;
int n,m,LYD,k,tot,to[N*2],next[N*2],last[N];
ll f[N][M],sum[N][M];
void link(int u,int v)
{
    to[++tot]=v,next[tot]=last[u],last[u]=tot;
}
ll s(int v,int x)
{
    if(x<=LYD) return sum[v][min(x,LYD)];
    if(x<=m-LYD) return (sum[v][LYD]+(x-LYD)*f[v][LYD+1]%mo)%mo;
    return (sum[v][LYD]+f[v][LYD+1]*(m-2*LYD)%mo+sum[v][LYD]-sum[v][m-x]+mo)%mo;
}
void dfs(int v,int fr)
{
    fo(i,1,LYD+1) f[v][i]=1;
    efo(i,v)
    {
        int u=to[i];
        if(u==fr) continue;
        dfs(u,v);
        fo(j,1,LYD+1)
        {
            ll t=0;
            if(j-k>0) t=s(u,j-k);
            if(j+k<=m) t=(t+s(u,m)-s(u,j+k-1)+mo)%mo;
            if(!k) t=(t-f[u][j]+mo)%mo;
            (f[v][j]*=t)%=mo;
        }
    }
    fo(i,1,LYD+1) sum[v][i]=(sum[v][i-1]+f[v][i])%mo;
}
int main()
{
    freopen("label.in","r",stdin);
    freopen("label.out","w",stdout);
    int _,u,v;
    for(scanf("%d",&_);_--;)
    {
        memset(f,0,sizeof(f));
        memset(sum,0,sizeof(sum));
        tot=0;
        memset(last,0,sizeof(last));
        scanf("%d %d %d",&n,&m,&k);
        fo(i,1,n-1)
        {
            scanf("%d %d",&u,&v);
            link(u,v),link(v,u);
        }
        LYD=min(m,10000);
        dfs(1,1);
        printf("%lld\n",s(1,m));
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值