传送门.

题解:

考虑若最后的总伤害数是s,那么就挡板分配一下,方案数是\(C_{s-1}^{n-1}\)。

那么问题在于总伤害数很大,不能一个一个的算。

\(C_{s-1}^{n-1}\)的OGF是\({x^{n-1}\over (1-x)^n}\)

由\(F=FA+R->F={R \over 1-A}\)

得到递推式\(A=1-(1-x)^n\),前面的项可以用组合数算出。

那么每次就是常系数齐次递推,每次搞的时候取模就好了。

复杂度是\(O(log^2)\)

题解给出了更加巧妙的方法,我们不直接求\(s\)伤害的方案数。

考虑\(f(x)\)表示任意伤害下, 分配给x个人的方案数。

当合并\(f、g\)两堆伤害时时,由于中间可以攃挡板,可以不插,所以就是\(f*g*(1+x)\)。

用NTT卷积,每次算完后只用保留前n项。

直接套快速幂是\(O(log^2)\)的,但是可以用exp优化。

初值利用这个式子就好了\(\sum_{i=y}^xC_{i}^y=C_{x+1}^{y+1}\)。

直到现在我才意识到杨辉三角的一条对角线和一列的求法是一样的,由于翻转一下就好了。

Code:

#include<bits/stdc++.h>
#define fo(i, x, y) for(int i = x, B = y; i <= B; i ++)
#define ff(i, x, y) for(int i = x, B = y; i < B; i ++)
#define fd(i, x, y) for(int i = x, B = y; i >= B; i --)
#define ll long long
#define pp printf
#define hh pp("\n")
using namespace std; const int mo = 998244353; ll ksm(ll x, ll y) {
ll s = 1;
for(; y; y /= 2, x = x * x % mo)
if(y & 1) s = s * x % mo;
return s;
} typedef vector<ll> V;
#define pb push_back
#define si size()
#define re resize namespace ntt {
const int nm = 262144;
ll w[nm], a[nm], b[nm]; int r[nm];
void build() {
for(int i = 1; i < nm; i *= 2) {
w[i] = 1;
ll v = ksm(3, (mo - 1) / 2 / i);
ff(j, 1, i) w[i + j] = w[i + j - 1] * v % mo;
}
}
void dft(ll *a, int n, int f) {
ff(i, 0, n) {
r[i] = r[i / 2] / 2 + (i & 1) * (n / 2);
if(i < r[i]) swap(a[i], a[r[i]]);
} ll b;
for(int i = 1; i < n; i *= 2) for(int j = 0; j < n; j += 2 * i) ff(k, 0, i)
b = a[i + j + k] * w[i + k], a[i + j + k] = (a[j + k] - b) % mo, a[j + k] = (a[j + k] + b) % mo;
if(f == -1) {
reverse(a + 1, a + n);
b = ksm(n, mo - 2);
ff(i, 0, n) a[i] = (a[i] + mo) * b % mo;
}
}
V operator * (V p, V q) {
int n0 = p.si + q.si - 1, n = 1;
while(n < n0) n *= 2;
ff(i, 0, n) a[i] = b[i] = 0;
ff(i, 0, p.si) a[i] = p[i];
ff(i, 0, q.si) b[i] = q[i];
dft(a, n, 1); dft(b, n, 1);
ff(i, 0, n) a[i] = a[i] * b[i] % mo;
dft(a, n, -1);
p.re(n0);
ff(i, 0, n0) p[i] = a[i];
return p;
}
void dft(V &p, int f) {
int n = p.si;
ff(i, 0, n) a[i] = p[i];
dft(a, n, f);
ff(i, 0, n) p[i] = a[i];
}
} using ntt :: operator *;
using ntt :: dft; V qni(V a) {
V b; b.re(1); b[0] = ksm(a[0], mo - 2);
for(int n = 2; n < a.si * 2; n *= 2) {
V c = a; c.re(n); c.re(2 * n); dft(c, 1);
b.re(2 * n); dft(b, 1);
ff(i, 0, 2 * n) b[i] = (2 * b[i] - c[i] * b[i] % mo * b[i]) % mo;
dft(b, -1); b.re(n);
}
b.re(a.si); return b;
} V qd(V a) {
fo(i, 0, a.si - 2) a[i] = a[i + 1] * (i + 1) % mo;
a.re(a.si - 1);
return a;
}
V jf(V a) {
a.re(a.si + 1);
fd(i, a.si - 1, 1) a[i] = a[i - 1] * ksm(i, mo - 2) % mo;
a[0] = 0;
return a;
} V ln(V a) {
int n = a.si;
a = jf(qd(a) * qni(a));
a.re(n);
return a;
} V exp(V a) {
V b; b.re(1); b[0] = 1;
for(int n = 1; n < a.si * 2; n *= 2) {
b.re(n);
V c = a; c.re(n);
V d = ln(b);
ff(i, 0, n) d[i] -= c[i];
d = d * b;
ff(i, 0, n) b[i] = (b[i] - d[i] + mo) % mo;
}
b.re(a.si); return b;
} const int N = 1e5 + 5; int n, m, a[N], b[N];
ll fac[N], nf[N]; void build(int n) {
fac[0] = 1;
fo(i, 1, n) fac[i] = fac[i - 1] * i % mo;
nf[n] = ksm(fac[n], mo - 2);
fd(i, n, 1) nf[i - 1] = nf[i] * i % mo;
} V p; V mul(V a, V b) {
a = a * b;
a.re(m);
fd(i, m - 1, 1) a[i] = (a[i] + a[i - 1]) % mo;
return a;
} V c; V ksm(V x, int y) {
if(y == 1) return x;
ll xc = x[0]; ll nc = ksm(xc, mo - 2);
ff(i, 0, m) x[i] = x[i] * nc % mo;
x = ln(x);
ff(i, 0, m) x[i] = x[i] * y % mo;
x = exp(x);
xc = ksm(xc, y);
ff(i, 0, m) x[i] = x[i] * xc % mo;
V d = c;
ff(i, 0, m) d[i] = d[i] * (y - 1) % mo;
d = exp(d);
x = x * d; x.re(m);
return x;
} V operator + (V a, V b) {
if(a.si < b.si) a.re(b.si);
ff(i, 0, b.si) a[i] = (a[i] + b[i]) % mo;
return a;
} V ans; int main() {
ntt :: build();
build(1e5);
scanf("%d %d", &m, &n);
c.re(2); c[0] = 1; c[1] = 1;
c.re(m); c = ln(c);
fo(i, 1, n) scanf("%d %d", &a[i], &b[i]);
fo(i, 1, n) {
p.clear(); p.re(m);
ll f = 1;
fo(j, 1, min(b[i], m)) {
f = f * (b[i] - j + 1) % mo;
p[j - 1] = f * nf[j] % mo;
}
p = ksm(p, a[i]);
if(i == 1) ans = p; else ans = mul(ans, p);
}
ll as = (ans[m - 1] % mo + mo ) % mo;
pp("%lld\n", as);
}

Comet OJ - Contest #11 E ffort(组合计数+多项式快速幂)的更多相关文章

  1. Comet OJ - Contest #11 题解&赛后总结

    Solution of Comet OJ - Contest #11 A.eon -Problem designed by Starria- 在模 10 意义下,答案变为最大数的最低位(即原数数位的最 ...

  2. Comet OJ - Contest #11题解

    传送门 \(A\) 咕咕咕 const int N=1e6+5; char s[N],t[N];int n,res; inline bool cmp(const int &x,const in ...

  3. Comet OJ - Contest #11 B题 usiness

    ###题目链接### 题目大意:一开始手上有 0 个节点,有 n 天抉择,m 种方案,在每天中可以选择任意种方案.任意次地花费 x 个节点(手上的节点数不能为负),使得在 n 天结束后,获得 y 个节 ...

  4. Comet OJ - Contest #11 B 背包dp

    Code: #include <bits/stdc++.h> #define N 1005 #define M 2000 #define setIO(s) freopen(s". ...

  5. Comet OJ - Contest #11 A 水题

    Code: #include <bits/stdc++.h> #define N 3000000 using namespace std; char str[N]; int main() ...

  6. Comet OJ - Contest #11 D isaster 重构树+倍增+dfs序+线段树

    发现对于任意一条边,起决定性作用的是节点编号更大的点. 于是,对于每一条边,按照节点编号较大值作为边权,按照最小生成树的方式插入即可. 最后用线段树维护 dfs 序做一个区间查询即可. Code: # ...

  7. Comet OJ - Contest #2 简要题解

    Comet OJ - Contest #2 简要题解 cometoj A 模拟,复杂度是对数级的. code B 易知\(p\in[l,r]\),且最终的利润关于\(p\)的表达式为\(\frac{( ...

  8. Comet OJ - Contest #2简要题解

    Comet OJ - Contest #2简要题解 前言: 我没有小裙子,我太菜了. A 因自过去而至的残响起舞 https://www.cometoj.com/contest/37/problem/ ...

  9. Comet OJ - Contest #4--前缀和

    原题:Comet OJ - Contest #4-B https://www.cometoj.com/contest/39/problem/B?problem_id=1577传送门 一开始就想着暴力打 ...

随机推荐

  1. sql格式化时间

    sql格式化date类型 DATE_FORMAT(nuw(), '%Y-%m-%d') sql格式化long类型时间 FROM_UNIXTIME(time/1000,'%Y-%m-%d')

  2. MyBatis注解开发-@Insert和@InsertProvider(@Select、@SelectProvider雷同)

    @Insert和@InsertProvider都是用来在实体类的Mapper类里注解保存方法的SQL语句.不同的是,@Insert是直接配置SQL语句,而@InsertProvider则是通过SQL工 ...

  3. InnoDB的LRU淘汰策略

    Reference: https://time.geekbang.org/column/article/121710 InnoDB存储引擎是基于集合索引实现的数据存储,也就是除了索引列以及主键是存储在 ...

  4. OC学习篇之---@class关键字的作用以及#include和#import的区别

    前一篇文章说到了OC中类的三大特性:http://blog.csdn.net/jiangwei0910410003/article/details/41707161今天我们来看一下在学习OC的过程中遇 ...

  5. Cisco基础(二):三层交换vlan间通信、多交换机vlan间通信、三层交换配置路由、RIP动态路由配置、三层交换配置RIP动态路由

    一.三层交换vlan间通信 目标: VLAN实现了广播域的隔离,同时也将VLAN间的通信隔离了.三层交换技术使得VLAN间可以通信. 通过三层交换实现VLAN间通信 方案: 为了解决了传统路由器低速. ...

  6. AcWing 225. 矩阵幂求和 (矩阵快速幂+分治)打卡

    题目:https://www.acwing.com/problem/content/227/ 题意:给你n,k,m,然后输入一个n阶矩阵A,让你求  S=A+A^2+A^3.+......+A^k 思 ...

  7. [CSP-S模拟测试]:E(贪心)

    题目传送门(内部题48) 输入格式 第一行一个整数$n$.接下来$n$行每行两个整数$x_i,y_i$. 输出格式 一行一个整数表示答案. 样例 样例输入$1$: 23 72 5 样例输出$1$: 样 ...

  8. php自带函数大全

    php自带函数大全 http://blog.csdn.net/hopewtc/article/details/6797326   Abs: 取得绝对值.Acos: 取得反余弦值.ada_afetch: ...

  9. 十二、SpringBoot 优雅的集成Spring Security

    前言 至于什么是Spring security ,主要两个作用,用户认证和授权.即我们常说的,用户只有登录了才能进行其他操作,没有登录的话就重定向到登录界面.有的用户有权限执行某一操作,而有的用户不能 ...

  10. 78、tensorflow滑动平均模型,用来更新迭代的衰减系数

    ''' Created on 2017年4月21日 @author: weizhen ''' #4.滑动平均模型 import tensorflow as tf #定义一个变量用于计算滑动平均,这个变 ...