0
点赞
收藏
分享

微信扫一扫

NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)

月白色的大狒 2022-07-12 阅读 58

​​传送门​​​ 题意:给定两个整数 NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_git 求 k 元组 NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_git_02 的个数,满足 NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_i++_03 为正整数
NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_git_04NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_i++_03 均不是 NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_5e_06的倍数
NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_i++_07

首先,如果没有 NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_5e_06 的限制,答案为 NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_i++_09,插板,先全部减去1
考虑 NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_5e_06 的限制,发现不好容斥
发现最后的序列一定没有 m 的倍数,并且如果一个数 NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_5e_11 ,可以将它表示为 NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_5e_12
于是我们可以将最后的序列抽象为先选好 NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_git_13,并强制让 NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_5e_14,再对 NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_5e_15 随便加几个 NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_5e_06
枚举 NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_5e_17NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_i++_18 为上文所述的 NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_i++_18,那么先选好的 NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_git_13 的条件可以抽象为:

  1. NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_git_21
  2. NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_git_22

然后在对几个 NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_5e_15 加上 NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_5e_06 的倍数,假设 NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_5e_25 的范围内有 NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_i++_26 个 m 的倍数
发现这个过程等价于把 NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_i++_26 分到 k 个集合,可以为空,方案数为 NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_5e_28
如何求第一个,一下令 NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_5e_06NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_git_30,考虑容斥,强制 NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_i++_31NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_5e_32
但如何求强制 NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_i++_31NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_5e_32 的个数呢,发现这个问题等价于选 i 个位置出来 NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_5e_35,然后将 NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_git_36 分配给这 NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_5e_37 个集合,最后再将这 NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_i++_31 个加上 NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_5e_06,于是有
NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_5e_40

最后的答案
NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_5e_41
NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_git_42,组合数暴力乘,有些不像 NOI.AC CSP-S 模拟 Round 2 T1 Count (组合数学) (容斥)_5e_43

#include<bits/stdc++.h>
#define cs const
using namespace std;
typedef long long ll;
ll read(){
ll cnt = 0, f = 1; char ch = 0;
while(!isdigit(ch)){ ch = getchar(); if(ch == '-') f = -1;}
while(isdigit(ch)) cnt = cnt*10 + (ch-'0'), ch = getchar();
return cnt * f;
}
cs int N = 1e7 + 5;
cs int Mod = 998244353;
int add(int a, int b){ return a + b >= Mod ? a + b - Mod : a + b;}
int mul(int a, int b){ return 1ll * a * b % Mod; }
void Add(int &a, int b){ a = add(a, b);}
ll n; int m, k, fac[N], inv[N];
int C(ll n, int m){
if(n < 0 || m < 0 || n < m) return 0;
if(n < N) return mul(fac[n], mul(inv[m], inv[n - m]));
else{
int ret = inv[m];
for(ll i = n; i >= n - m + 1; i--) ret = mul(ret, i % Mod);
return ret;
}
}
int g(ll n, int m){
// devide n into m group and the group can be empty
if(n < 0) return 0;
return C(n + m - 1, m - 1);
}
int f(int n, int m, int k){
// devide n into m group that the size of each group is less than k
// can not be empty
n -= m; if(n < 0) return 0;
int ans = 0;
for(int i = 0; i <= m; i++){
int ret = mul(g(n - i * k, m), C(m, i));
(i & 1) ? Add(ans, Mod - ret) : Add(ans, ret);
} return ans;
}
int main(){
n = read(), m = read(), k = read();
fac[0] = fac[1] = inv[0] = inv[1] = 1;
for(int i = 2; i < N; i++) fac[i] = mul(fac[i-1], i);
for(int i = 2; i < N; i++) inv[i] = mul(Mod-Mod/i, inv[Mod%i]);
for(int i = 2; i < N; i++) inv[i] = mul(inv[i], inv[i-1]);
// 枚举 < m 的数的和
ll r = n % m; int ans = 0;
for(int i = 0; i < k; i++){
Add(ans, mul(f(i * m + r, k, m - 1), g((n - r) / m - i, k)));
} cout << ans; return 0;
}


举报

相关推荐

0 条评论