• AtCoder Beginner Contest 217G


    从小清新题目开始的康复之旅

    G - Groups

    Problem Statement

    You are given positive integers $N$ and $M$. For each $k=1,…,N$, solve the following problem.

    • Problem: We will divide $N$ people with ID numbers $1$ through $N$ into $k$ non-empty groups. Here, people whose ID numbers are equal modulo $M$ cannot belong to the same group.
      How many such ways are there to divide people into groups?
      Since the answer may be enormous, find it modulo $998244353$.

    Here, two ways to divide people into groups are considered different when there is a pair $(x,y)$ such that Person $x$ and Person $y$ belong to the same group in one way but not in the other.

    Constraints

    • $2≤N≤5000$
    • $2≤M≤N$
    • All values in input are integers.

    题目分析

    一个组合数学题

    一开始想简单了,以为是一个最简单的容斥,考虑最多分成n组的情况减去最多分成n-1组的情况,以为这个就是恰好n组的情况

    递推地看第n项的答案f(n),首先钦定某一个剩余类$a_1$的位置,其余的剩余类$a_j$随意插空有$Pi A(n, a_j)$种方案,然后减去恰好包含$n-1$项$f(n-1)*A(n-a_1,(n-1)-a_1)$,$n-2$项$f(n-2)*A(n-a_1,(n-2)-a_1)$...的方案。最后因为方案是无序的,再除以$(n-a_1)!$

    CE了一发emmm根本没想起来atcoder不能用万能头

    // #include<bits/stdc++.h>
    #include<cstdio>
    const int MO = 998244353;
    const int maxn = 5035;
    
    int n,m,a[maxn],f[maxn],fac[maxn],inv[maxn];
    
    int A(int n, int m)
    {
        return 1ll*fac[n]*inv[n-m]%MO;
    }
    int C(int n, int m)
    {
        return 1ll*fac[n]*inv[n-m]%MO*inv[m]%MO;
    }
    void Inc(int &x, int y)
    {
        x = (x+y+MO)%MO;
    }
    void Dec(int &x, int y)
    {
        x = (x-y+MO)%MO;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for (int i=1; i<=n%m; i++) a[i] = n/m+1;
        for (int i=n%m+1; i<=m; i++) a[i] = n/m;
        inv[0] = inv[1] = fac[1] = 1;
        for (int i=2; i<=n; i++)
            inv[i] = 1ll*(MO-MO/i)*inv[MO%i]%MO;
        for (int i=2; i<=n; i++)
            inv[i] = 1ll*inv[i-1]*inv[i]%MO, fac[i] = 1ll*fac[i-1]*i%MO;
        for (int i=1; i<a[1]; i++) f[i] = 0;
        for (int i=a[1]; i<=n; i++)
        {
            int cnt = 1;
            for (int j=2; j<=m; j++)
                cnt = 1ll*cnt*A(i, a[j])%MO;
            Inc(f[i], cnt);
            for (int j=a[1]; j<i; j++)
                Dec(f[i], 1ll*f[j]*A(i-a[1], j-a[1])%MO);
            f[i] = 1ll*f[i]*inv[i-a[1]]%MO;
        }
        for (int i=1; i<=n; i++) printf("%d
    ",f[i]);
        return 0;
    }

    END

  • 相关阅读:
    <记录> axios 模拟表单提交数据
    PHP 设计模式(一)
    CSS3中translate、transform和translation的区别和联系
    微信小程序 支付功能 服务器端(TP5.1)实现
    微信小程序 用户登录 服务器端(TP5.1)实现
    <记录> curl 封装函数
    <记录>TP5 关联模型使用(嵌套关联、动态排序以及隐藏字段)
    PHP/TP5 接口设计中异常处理
    TP5 自定义验证器
    高并发和大流量解决方案--数据库缓存
  • 原文地址:https://www.cnblogs.com/antiquality/p/15270012.html
Copyright © 2020-2023  润新知