cf855 C. Helga Hufflepuff's Cup

题意:

在给定的一棵树上给节点染色。可以染m种颜色。定义一种特殊颜色mx,一棵树上最多能有mc个mx;如果一个节点为mx,那么他相邻的节点的值只能选比他小的颜色。问染色方案数。

n1e5,1m1e9,1mc10

思路:

f(u,0/1/2,i) 表示 u 节点染 [1,mx]/mx/[mx+1,m] ,以 u 为根的树中有 imx 的方案数。答案为 Σf(1,02,0mc)

每次树形dp都要解决这样一个问题:有 soncnt+1 堆石子,已知在每堆石子中选 0,1,2,mc 个的方案数,求一共选 0,1,2,mc 个的方案数。

这(大概)是个背包问题,枚举之前已经选的个数 i,现在要从新的堆中选的个数 j 进行转移。要开个备份数组。

ll n, m, mx, mc, f[N][3][11], g[3][11];

void dfs(int u, int fa) {
    f[u][0][0] = mx - 1, f[u][1][1] = 1, f[u][2][0] = m - mx;

    for(int v : G[u]) if(v != fa) {
        dfs(v, u);

        memset(g, 0, sizeof g);

        for(int i = 0; i <= mc; i++)
        for(int j = 0; i + j <= mc; j++)
            add(g[0][i+j], f[u][0][i] * (f[v][0][j] + f[v][1][j] + f[v][2][j])),
            add(g[1][i+j], f[u][1][i] * f[v][0][j]),
            add(g[2][i+j], f[u][2][i] * (f[v][0][j] + f[v][2][j]));

        memcpy(f[u], g, sizeof g);
    }
}

signed main() {
    iofast;
    cin >> n >> m;
    for(int i = 1, a, b; i < n; i++)
        cin >> a >> b, G[a].pb(b), G[b].pb(a);
    cin >> mx >> mc;

    dfs(1, 0);

    int ans = 0;
    for(int i = 0; i < 3; i++)
        for(int j = 0; j <= mc; j++)
            (ans += f[1][i][j]) %= mod;
    cout << ans;
}

posted @   Bellala  阅读(56)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示