• bzoj2159


    树形dp+第二类斯特林数

    又是这种形式,只不过这次不用伯努利数了

    直接搞肯定不行,我们化简一下式子,考虑x^n的组合意义,是把n个物品放到x个箱子里的方案数。那么就等于这个i=1->n,sigma(s[n,i]*A(x,i)),就是枚举要分成几组,这个用斯特林数算,然后把这些组放进箱子里,那么就是A(x,i),A是排列,但是这样还是不行,我们把A(x,i)=C(x,i)*i!,这样就行了,阶乘和斯特林数可以提出来,只要预处理一个点的组合数就行了,也就是∑i=1->n ∑ j=1->k C(dis(u,i),j),这个东西我们可以利用组合数的性质dp,也就是c[i][j]=c[i-1][j]+c[i-1][j-1],记住要减去重复的

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 1e5 + 5, M = 155, P = 10007;
    int n, m, L, now, A, B, Q;
    int s[M][M], up[N][M], down[N][M], fac[M];
    vector<int> G[N]; 
    void dfs(int u, int last)
    {
        down[u][0] = 1;
        for(int i = 0; i < G[u].size(); ++i) 
        {
            int v = G[u][i];
            if(v == last) continue;
            dfs(v, u);
            down[u][0] = (down[u][0] + down[v][0]) % P;
            for(int j = 1; j <= m; ++j) down[u][j] = ((down[u][j] + (down[v][j - 1] + down[v][j]) % P) % P) % P;
        }
    }
    void dfs1(int u, int last)
    {
        if(last) 
        {
            up[u][0] = n - down[u][0];
            for(int i = 1; i <= m; ++i)
            {
                up[u][i] = (up[u][i] + ((up[last][i] + up[last][i - 1] + down[last][i] + down[last][i - 1] - down[u][i] - (down[u][i - 1] << 1)) % P + P) % P) % P;
                if(i > 1) up[u][i] = ((up[u][i] - down[u][i - 2]) % P + P) % P;
            }
        }
        for(int i = 0; i < G[u].size(); ++i) 
        {
            int v = G[u][i];
            if(v == last) continue;
            dfs1(v, u); 
        }
    }
    int main()
    {
        scanf("%d%d%d%d%d%d%d", &n, &m, &L, &now, &A, &B, &Q);  
        for(int i = 1; i < n; ++i)
        {  
            now = (now * A + B) % Q; 
            int tmp = min(i, L);  
            int u = i - now % tmp, v = i + 1;  
            G[u].push_back(v);
            G[v].push_back(u);
        }  
        s[0][0] = fac[0] = 1;
        for(int i = 1; i <= m; ++i)
        {
            fac[i] = fac[i - 1] * i % P;
            for(int j = 1; j <= m; ++j) 
                s[i][j] = (s[i - 1][j] * j % P + s[i - 1][j - 1]) % P;
        }
        dfs(1, 0);
        dfs1(1, 0);
        for(int i = 1; i <= n; ++i) 
        {
            int ans = 0;
            for(int j = 1; j <= m; ++j) ans = (ans + s[m][j] * fac[j] % P * (up[i][j] + down[i][j]) % P) % P; 
            printf("%d
    ", ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    vue3自定义指令过滤input的输入内容
    我的收藏周刊011
    我的收藏周刊012
    20192416《系统与网络攻防技术》实验八实验报告
    Dapr学习(3)之服务调用概述
    摄影后期调色RAW数码照片图像HDR全景制作Lightroom(Lr)2022(Mac/win)
    新入手的苹果电脑需要安装的几款工具
    图片编辑工具Photoshop 2022中文
    Xmind 2022激活版终于等到你!
    矢量图像绘图设计(AI 2022)Illustrator 2022中文
  • 原文地址:https://www.cnblogs.com/19992147orz/p/8036379.html
Copyright © 2020-2023  润新知