LOJ3120

52pts

\(N - D >= 2M\)或者\(M = 0\)那么就是\(D^{N}\)

只和数字的奇偶性有关,如果有k个奇数,那么必须满足\(N - k >= 2M\)

所以设\(f[i][j]\)表示第\(i\)个数有\(j\)个奇数的方案数,\(j\cdot f[i][j] \rightarrow f[i + 1][j - 1]\)和\((D - j) \cdot f[i][j] \rightarrow f[i + 1][j + 1]\)

64pts

这个只需要把上面的矩阵快速幂优化,只不过需要一点小技巧来卡一卡常……具体看代码吧

+8pts?

如果m = 1,不合法的只有每个数都不一样的情况

m = 2除去每个数都不一样的情况,有一个数大于1的情况且这个多少为2或3

以上就有72pts了!快落!

剩下的我就不会了,然后翻翻网上的题解写了一个容斥做法

至少k个方案数

奇数的序列的指数生成函数是

\(\frac{e^{x} - e^{-x}}{2} = \frac{x^{1}}{1!} + \frac{x^{3}}{3!} + \frac{x^{5}}{5!}....\)

至少有\(i\)个数为奇数的方案数

\(f_{i} = \binom{D}{i}n![x^{n}](\frac{e^{x} - e^{-x}}{2})^{i}e^{(D - i)x}\)

把\(2^{-i}\)提出去

\(f_{i} = \frac{\binom{D}{i}}{2^{i}} n!(e^{x} - e^{-x})^{i}e^{(D - i)x}\)

方案数是

然后把那个二项式展开一下

\(f_{i} = \frac{\binom{D}{i}}{2^{i}}n!e^{(D - i)x}\sum_{j = 0}^{i} (-1)^{j}e^{-jx}e^{(i - j)x}\binom{i}{j}[x^{n}]\)

合并一下就是

\(f_{i} = \frac{\binom{D}{i}}{2^{i}}n!\sum_{j = 0}^{i} (-1)^{j}e^{(D - 2j)x}\binom{i}{j}[x^{n}]\)

由于\(e^{ax}\)的第n项生成函数是\(\frac{a^{n}}{n!}\)

所以最后就是

\(f_{i} = \frac{i!\binom{D}{i}}{2^{i}}\sum_{j = 0}^{i} (-1)^{j}\frac{(D - 2j)^n}{j!(i - j)!}[x^{n}]\)

可以卷积算出来

然后

\(g_{i} = \sum_{j = i}^{D} (-1)^{j - i}\binom{i}{j}f_{j}\)

这个卷积一下也可以算

代码

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int, int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 2005
#define ba 47
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template <class T>
void read(T &res) {
res = 0;
T f = 1;
char c = getchar();
while (c < '0' || c > '9') {
if (c == '-')
f = -1;
c = getchar();
}
while (c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template <class T>
void out(T x) {
if (x < 0) {
x = -x;
putchar('-');
}
if (x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
const int MOD = 998244353;
int D, N, M;
int fac[1000005], invfac[1000005];
int inc(int a, int b) { return a + b >= MOD ? a + b - MOD : a + b; }
int mul(int a, int b) { return 1LL * a * b % MOD; }
int C(int n, int m) {
if (n < m)
return 0;
return mul(fac[n], mul(invfac[m], invfac[n - m]));
}
void update(int &x, int y) { x = inc(x, y); }
int fpow(int x, int c) {
int res = 1, t = x;
while (c) {
if (c & 1)
res = mul(res, t);
t = mul(t, t);
c >>= 1;
}
return res;
}
namespace task1 {
int f[2][4005];
void Main() {
int cur = 0;
f[cur][0] = 1;
for (int i = 1; i <= N; ++i) {
memset(f[cur ^ 1], 0, sizeof(f[cur ^ 1]));
for (int j = 0; j <= D; ++j) {
if (j >= 1)
update(f[cur ^ 1][j - 1], mul(f[cur][j], j));
update(f[cur ^ 1][j + 1], mul(f[cur][j], D - j));
}
cur ^= 1;
}
int ans = 0;
for (int i = 0; i <= D; ++i) {
if (N - i >= 2 * M)
update(ans, f[cur][i]);
}
out(ans);
enter;
}
} // namespace task1
namespace task2 {
vector<int> v1[305], v2[305];
struct Matrix {
int f[305][305];
Matrix() { memset(f, 0, sizeof(f)); }
friend Matrix operator*(const Matrix &a, const Matrix &b) {
Matrix c;
for (int i = 0; i <= D; ++i) {
v1[i].clear();
v2[i].clear();
}
for (int i = 0; i <= D; ++i) {
for (int j = 0; j <= D; ++j) {
if (a.f[i][j])
v1[i].pb(j);
if (b.f[i][j])
v2[i].pb(j);
}
}
for (int i = 0; i <= D; ++i) {
for (auto k : v1[i]) {
for (auto j : v2[k]) {
update(c.f[i][j], mul(a.f[i][k], b.f[k][j]));
}
}
}
return c;
}
} a, ans;
Matrix fpow(Matrix x, int c) {
Matrix res = x, t = x;
--c;
while (c) {
if (c & 1)
res = res * t;
t = t * t;
c >>= 1;
}
return res;
}
void Main() {
for (int i = 0; i <= D; ++i) {
if (i >= 1)
update(a.f[i][i - 1], i);
update(a.f[i][i + 1], D - i);
}
ans = fpow(a, N);
int res = 0;
for (int i = 0; i <= D; ++i) {
if (N - i >= 2 * M) {
update(res, ans.f[0][i]);
}
}
out(res);
enter;
}
} // namespace task2
namespace task3 {
const int MAXL = (1 << 20);
int W[MAXL + 5];
vector<int> a, b, f, g;
void NTT(vector<int> &p, int L, int on) {
p.resize(L);
for (int i = 1, j = L >> 1; i < L - 1; ++i) {
if (i < j)
swap(p[i], p[j]);
int k = L >> 1;
while (j >= k) {
j -= k;
k >>= 1;
}
j += k;
}
for (int h = 2; h <= L; h <<= 1) {
int wn = W[(MAXL + on * MAXL / h) % MAXL];
for (int k = 0; k < L; k += h) {
int w = 1;
for (int j = k; j < k + h / 2; ++j) {
int u = p[j], t = mul(p[j + h / 2], w);
p[j] = inc(u, t);
p[j + h / 2] = inc(u, MOD - t);
w = mul(w, wn);
}
}
}
if (on == -1) {
int invL = fpow(L, MOD - 2);
for (int i = 0; i < L; ++i) {
p[i] = mul(p[i], invL);
}
}
}
vector<int> operator*(vector<int> a, vector<int> b) {
vector<int> c;
int t = a.size() + b.size() - 2, l = 1;
while (l <= t) l <<= 1;
c.resize(l);
NTT(a, l, 1);
NTT(b, l, 1);
for (int i = 0; i < l; ++i) c[i] = mul(a[i], b[i]);
NTT(c, l, -1);
return c;
}
void Init() {
W[0] = 1;
W[1] = fpow(3, (MOD - 1) / MAXL);
for (int i = 2; i < MAXL; ++i) W[i] = mul(W[i - 1], W[1]);
}
void Main() {
Init();
a.resize(D + 1);
b.resize(D + 1);
int t = 1;
for (int i = 0; i <= D; ++i) {
a[i] = mul(mul(t, fpow(inc(D, MOD - 2 * i), N)), invfac[i]);
b[i] = invfac[i];
t = mul(t, MOD - 1);
}
f = a * b;
f.resize(D + 1);
t = 1;
for (int i = 0; i <= D; ++i) {
f[i] = mul(f[i], fac[D]);
f[i] = mul(f[i], invfac[D - i]);
f[i] = mul(f[i], t);
t = mul(t, (MOD + 1) / 2);
}
a.clear();
a.resize(D + 1);
t = 1;
for (int i = 0; i <= D; ++i) {
a[D - i] = mul(t, invfac[i]);
f[i] = mul(f[i], fac[i]);
t = mul(t, MOD - 1);
}
g = a * f;
int L = N - 2 * M;
int ans = 0;
for (int i = 0; i <= L; ++i) {
update(ans, mul(g[i + D], invfac[i]));
}
out(ans);
enter;
}
} // namespace task3
int main() {
#ifdef ivorysi
freopen("f1.in", "r", stdin);
#endif
fac[0] = 1;
for (int i = 1; i <= 1000000; ++i) fac[i] = mul(fac[i - 1], i);
invfac[1000000] = fpow(fac[1000000], MOD - 2);
for (int i = 999999; i >= 0; --i) invfac[i] = mul(invfac[i + 1], i + 1);
read(D);
read(N);
read(M);
if (N - D >= 2 * M || M == 0) {
out(fpow(D, N));
enter;
} else if (N <= 4000)
task1::Main();
else if (D <= 300)
task2::Main();
else if (M == 1) {
int ans = fpow(D, N);
if (D >= N) {
update(ans, MOD - mul(fac[D], invfac[D - N]));
}
out(ans);
enter;
} else if (M == 2) {
int ans = fpow(D, N);
if (D >= N) {
update(ans, MOD - mul(fac[D], invfac[D - N]));
}
for (int j = 2; j <= 3; ++j) {
if (N - j <= D - 1) {
int t = mul(D, C(D - 1, N - j));
update(ans, MOD - mul(mul(t, invfac[j]), fac[N]));
}
}
out(ans);
enter;
} else {
task3::Main();
}
return 0;
}

【LOJ】#3120. 「CTS2019 | CTSC2019」珍珠的更多相关文章

  1. @loj - 3120@ 「CTS2019 | CTSC2019」珍珠

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 有 \(n\) 个在范围 \([1, D]\) 内的整数均匀随机 ...

  2. Loj #3124. 「CTS2019 | CTSC2019」氪金手游

    Loj #3124. 「CTS2019 | CTSC2019」氪金手游 题目描述 小刘同学是一个喜欢氪金手游的男孩子. 他最近迷上了一个新游戏,游戏的内容就是不断地抽卡.现在已知: - 卡池里总共有 ...

  3. LOJ 3120: 洛谷 P5401: 「CTS2019 | CTSC2019」珍珠

    题目传送门:LOJ #3120. 题意简述: 称一个长度为 \(n\),元素取值为 \([1,D]\) 的整数序列是合法的,当且仅当其中能够选出至少 \(m\) 对相同元素(不能重复选出元素). 问合 ...

  4. LOJ 3124 「CTS2019 | CTSC2019」氪金手游——概率+树形DP

    题目:https://loj.ac/problem/3124 看了题解:https://www.cnblogs.com/Itst/p/10883880.html 先考虑外向树. 考虑分母是 \( \s ...

  5. loj3120 「CTS2019 | CTSC2019」珍珠

    link .... 感觉自己太颓废了....还是来更题解吧...[话说写博客会不会涨 rp 啊 qaq ? 题意: 有 n 个物品,每个都有一个 [1,D] 中随机的颜色,相同颜色的两个物品可以配对. ...

  6. LOJ #3119「CTS2019 | CTSC2019」随机立方体 (容斥)

    博客链接 里面有个下降幂应该是上升幂 还有个bk的式子省略了k^3 CODE 蛮短的 #include <bits/stdc++.h> using namespace std; const ...

  7. LOJ #3119. 「CTS2019 | CTSC2019」随机立方体 组合计数+二项式反演

    好神的一道计数题呀. code: #include <cstdio> #include <algorithm> #include <cstring> #define ...

  8. 「CTS2019 | CTSC2019」氪金手游 解题报告

    「CTS2019 | CTSC2019」氪金手游 降 智 好 题 ... 考场上签到失败了,没想容斥就只打了20分暴力... 考虑一个事情,你抽中一个度为0的点,相当于把这个点删掉了(当然你也只能抽中 ...

  9. 「CTS2019 | CTSC2019」随机立方体 解题报告

    「CTS2019 | CTSC2019」随机立方体 据说这是签到题,但是我计数学的实在有点差,这里认真说一说. 我们先考虑一些事实 如果我们在位置\((x_0,y_0,z_0)\)钦定了一个极大数\( ...

随机推荐

  1. 洛谷P2789 直线交点数 [数论,递归]

    题目传送门 题目描述 平面上有N条直线,且无三线共点,那么这些直线能有多少不同的交点数? 输入格式 一个正整数N 输出格式 一个整数表示方案总数 输入输出样例 输入 #1 4 输出 #1 5 说明/提 ...

  2. 【csp模拟赛4】 珠江夜游 (cruise.cpp)-二分,贪心

    Problem 1 珠江夜游 (cruise.cpp) [题目描述] 小 Z 放假后难得来一趟广州游玩,当然要吃遍广州各路美食小吃然后再 到珠江新城看看远近闻名的小蛮腰啦!可当小 Z 一路吃吃吃以后, ...

  3. MySQL Innodb引擎和MyIASM引擎的区别

    Innodb引擎 Innodb引擎提供了对数据库ACID事务的支持,并且实现了SQL标准的四种隔离级别.该引擎还提供了行级锁和外键约束,它的设计目标是处理大容量数据库系统,它本身其实就是基于MySQL ...

  4. 7.20套娃(tao)

    套娃(tao) input7 39 53 710 65 102 610 104 110 53 53 9output012 sol: 把查询想象成(x1,y1)向(x2,y2)有边当且仅当(x1< ...

  5. Jquery 2.0+版本不支持IE8,如何解决?

    用了JQuery2.0+以后,在IE8下会报错,下面是我的方法. 先看代码: <!--[if !IE]> -->        <script src="/Scrip ...

  6. 5.rabbitmq--通配符模式Topics

    rabbitmq--通配符模式Topics topic模式也称为主题模式,其实他相对于routing模式最大的好处就是他多了一种匹配模式的路由,怎么理解匹配呢,其实就相当于我们之前正则的.*这种,不过 ...

  7. mybatis中的foreach条件参数过多时,#和$效率比较

    在客户端查询都小于1秒. 测试: mybatis中in条件12.3万数据$ : 6051 ms# : 27045 ms 1.2万数据$ : 1154 ms# : 24387 ms 5 万数据$ : 2 ...

  8. 1分钟快速制作漂亮的Html5本地记事本

    大家好,以前给大家分享过一个五步骤制作精美的HTML5时钟的文章,点击回顾<五步教你制作漂亮精致的HTML时钟>,还有<一分钟教你如何实现唯美的文字描边>:今天给大家分享一个用 ...

  9. JS基础_数组简介

    内建对象 宿主对象 自定义对象 数组(Array) - 数组也是一个对象 - 它和我们普通的对象功能类似,也是用来存储一些值的 - 不同的是普通对象是使用字符串作为属性名的 数组是使用数字来作为索引来 ...

  10. 工具类注入需要的service

    /** * 从redis获取信息 * @author yy * */ @Component//关键一:添加此注解才能被spring扫描到 public class CacheUtil { privat ...