链接:https://www.nowcoder.com/acm/contest/144/C
来源:牛客网
The input starts with one line containing exactly one integer T which is the number of test cases. (1 ≤ T ≤ 20)
Each test case contains one line with two integers N and M indicating the number of sets and the range of integers. (1 ≤ N ≤ 10
18
, 1 ≤ M ≤ 10
18
,
)
For each test case, output "Case #x: y" in one line (without quotes), where x is the test case number (starting from 1) and y is the number of different results modulo 998244353.
Case #1: 4 Case #2: 52
题意:有n个set(没有重复元素),有无限个1~m,第i次操作可以从中选一个元素往set i~n里面插入
求有多少种可能结果(只要有一个set不是完全相同)
分析:
参考博客:
AC代码:
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <vector>
#include <string>
#include <bitset>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <algorithm>
#define ls (r<<1)
#define rs (r<<1|1)
#define debug(a) cout << #a << " " << a << endl
using namespace std;
typedef long long ll;
const ll maxn = 1e6 + 10;
const double eps = 1e-8;
const ll mod = 998244353;
const ll inf = 1e9;
const double pi = acos(-1.0);
ll inv[maxn];
ll qow( ll a, ll b ) {
ll ans = 1;
while(b) {
if(b&1) {
ans = ans*a%mod;
}
a = a*a%mod;
b /= 2;
}
return ans;
}
void init() { //求阶乘逆元
inv[1] = 1;
for( ll i = 2; i <= maxn-10; i ++ ) {
inv[i] = (mod-mod/i)*inv[mod%i]%mod;
}
}
int main() {
ll T;
scanf("%lld",&T);
init();
for( ll cas = 1, n, m; cas <= T; cas ++ ) {
scanf("%lld%lld",&n,&m);
ll A = m%mod, C = 1, ans = 0, M = min(n,m);
n = n%mod, m = m%mod;
for( ll i = 1; i <= M; i ++ ) {
ans += A*C%mod;
ans %= mod;
A = (m-i)%mod*A%mod, C = (n-i)%mod*C%mod*inv[i]%mod;
}
printf("Case #%lld: %lld\n",cas,ans);
}
return 0;
}
牛客多校第六场 C Generation I 组合数学 阶乘逆元模板
原文:https://www.cnblogs.com/l609929321/p/9560261.html