[洛谷P5075][JSOI2012]分零食
题目大意:有$m(m\leqslant10^8)$个人站成一排,有$n(n\leqslant10^4)$个糖果,若第$i$个人没有糖果,那么第$i+1$个人也没有糖果。一个人有$x$个糖果会获得快乐值$v(x)$。
$$
v(x)=
\begin{cases}
ax^2+bx+c&(x>1)\\
1&(x=1)
\end{cases}
$$
一个方案的价值为$\prod\limits_{i=1}^mv(s_i)$($s_i$为第$i$个人得到的糖果数)。问所有方案的价值和,对$mod(mod\leqslant255)$取模
题解:令$f(x)=\sum\limits_{i=1}^{\infty}v(i)x^i$,那么$k$个人全部得到糖果的方案数是$[x^n]f^k(x)$。
$$
\begin{align*}
ans&=[x^n]\sum\limits_{i=1}^mf^i(x)\\
&=[x^n]\sum\limits_{i=0}^mf^i(x)\\
&=[x^n]\dfrac{1-f^{m+1}(x)}{1-f(x)}
\end{align*}
$$
注意这里的模数不是质数,但很小,可以用一模$NTT$,注意求逆部分,需要多把点值转成系数,因为负数无法表示。
卡点:$NTT$预处理部分度数没有加,调了一个上午。。。
C++ Code:
#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 32768
const int mod = 998244353;
namespace Math {
inline int pw(int base, int p) {
static int res;
for (res = 1; p; p >>= 1, base = static_cast<long long> (base) * base % mod) if (p & 1) res = static_cast<long long> (res) * base % mod;
return res;
}
inline int inv(int x) { return pw(x, mod - 2); }
}
inline void reduce(int &x) { x += x >> 31 & mod; }
inline void clear(register int *l, const int *r){
if(l >= r) return ;
while (l != r) *l++ = 0;
} int n, m, a, b, c, pmod;
namespace Poly {
#define N maxn
int lim, s, rev[N];
int Wn[N + 1];
inline void init(const int n) {
lim = 1, s = -1; while (lim < n) lim <<= 1, ++s;
for (register int i = 1; i < lim; ++i) rev[i] = rev[i >> 1] >> 1 | (i & 1) << s;
const int t = Math::pw(3, (mod - 1) / lim);
*Wn = 1; for (register int *i = Wn; i != Wn + lim; ++i) *(i + 1) = static_cast<long long> (*i) * t % mod;
}
inline void NTT(int *A, const int op = 1) {
for (register int i = 1; i < lim; ++i) if (i < rev[i]) std::swap(A[i], A[rev[i]]);
for (register int mid = 1; mid < lim; mid <<= 1) {
const int t = lim / mid >> 1;
for (register int i = 0; i < lim; i += mid << 1)
for (register int j = 0; j < mid; ++j) {
const int X = A[i + j], Y = static_cast<long long> (A[i + j + mid]) * Wn[j * t] % mod;
reduce(A[i + j] += Y - mod), reduce(A[i + j + mid] = X - Y);
}
}
if (!op) {
const int ilim = Math::inv(lim);
for (register int *i = A; i != A + lim; ++i) *i = static_cast<long long> (*i) * ilim % mod;
std::reverse(A + 1, A + lim);
}
} inline void INV(int *A, int *B, int n) {
if (n == 1) { *B = 1; return ; }
static int C[N];
const int len = n + 1 >> 1;
INV(A, B, len);
init(n + n - 1);
std::copy(A, A + n, C), clear(C + n, C + lim);
NTT(C), NTT(B);
for (register int i = 0; i < lim; ++i) C[i] = static_cast<long long> (C[i]) * B[i] % mod;
NTT(C, 0), clear(C + n, C + lim);
for (int *i = C; i != C + n; ++i) *i = pmod - *i % pmod;
C[0] += 2, NTT(C);
for (int i = 0; i < lim; ++i) B[i] = static_cast<long long> (B[i]) * C[i] % mod;
NTT(B, 0);
for (int *i = B; i != B + n; ++i) *i %= pmod;
clear(B + n, B + lim);
}
inline void PW(int *A, int *B, int n, int p) {
static int C[N], D[N];
std::copy(A, A + n, C);
init(n + n - 1);
B[0] = 1, clear(B + 1, B + lim);
while (p) {
if (p & 1) {
std::copy(C, C + n, D), clear(D + n, D + lim);
NTT(B), NTT(D);
for (int i = 0; i < lim; ++i) B[i] = static_cast<long long> (B[i]) * D[i] % mod;
NTT(B, 0), clear(B + n, B + lim);
for (int *i = B; i != B + n; ++i) *i %= pmod;
}
if (p >>= 1) {
NTT(C);
for (int *i = C; i != C + lim; ++i) *i = static_cast<long long> (*i) * *i % mod;
NTT(C, 0), clear(C + n, C + lim);
for (int *i = C; i != C + n; ++i) *i %= pmod;
}
}
}
#undef N
} int f[maxn], A[maxn], B[maxn];
int main() {
scanf("%d%d", &n, &pmod); ++n;
scanf("%d%d%d%d", &m, &a, &b, &c);
m = std::min(m, n - 1);
for (int i = 1; i < n; ++i) f[i] = (i * i % pmod * a + i * b + c) % pmod; Poly::PW(f, A, n, m + 1);
for (int *i = A; i != A + n; ++i) *i = pmod - *i; ++*A;
for (int *i = f; i != f + n; ++i) *i = pmod - *i; ++*f;
Poly::INV(f, B, n); Poly::init(n + n - 1);
Poly::NTT(A), Poly::NTT(B);
for (int i = Poly::lim; ~i; --i) A[i] = static_cast<long long> (A[i]) * B[i] % mod;
Poly::NTT(A, 0); printf("%d\n", A[n - 1] % pmod);
return 0;
}
[洛谷P5075][JSOI2012]分零食的更多相关文章
- 【BZOJ 4332】 4332: JSOI2012 分零食 (FFT+快速幂)
4332: JSOI2012 分零食 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 119 Solved: 66 Description 这里是欢乐 ...
- [BZOJ 4332] [JSOI2012]分零食(DP+FFT)
[BZOJ 4332] [JSOI2012]分零食(DP+FFT) 题面 同学们依次排成了一列,其中有A位小朋友,有三个共同的欢乐系数O,S和U.如果有一位小朋友得到了x个糖果,那么她的欢乐程度就是\ ...
- 洛谷 P5233 - [JSOI2012]爱之项链(Polya 定理+递推)
洛谷题面传送门 首先很明显题目暗示我们先求出符合条件的戒指数量,再计算出由这些戒指能够构成的项链的个数,因此考虑分别计算它们.首先是计算符合条件的戒指数量,题目中"可以通过旋转重合的戒指视作 ...
- bzoj4332;vijos1955:JSOI2012 分零食
描述 这里是欢乐的进香河,这里是欢乐的幼儿园. 今天是2月14日,星期二.在这个特殊的日子里,老师带着同学们欢乐地跳着,笑着.校长从幼儿园旁边的小吃店买了大量的零食决定分给同学们.听到这个消息,所有同 ...
- bzoj 4332:JSOI2012 分零食
描述 这里是欢乐的进香河,这里是欢乐的幼儿园. 今天是2月14日,星期二.在这个特殊的日子里,老师带着同学们欢乐地跳着,笑着.校长从幼儿园旁边的小吃店买了大量的零食决定分给同学们.听到这个消息,所有同 ...
- 洛谷P1154 奶牛分厩
P1154 奶牛分厩 173通过 481提交 题目提供者该用户不存在 标签高性能 难度普及- 时空限制1s / 128MB 提交 讨论 题解 最新讨论更多讨论 测试点3??? 求助!超时了 我抗议 ...
- bzoj 4332: JSOI2012 分零食 快速傅立叶变换
题目: Description 同学们依次排成了一列,其中有A位小朋友,有三个共同的欢乐系数O,S和U.如果有一位小朋友得到了x个糖果,那么她的欢乐程度就是\(f(x)=O*x^2+S*x+U\) 现 ...
- 洛谷——P1154 奶牛分厩
P1154 奶牛分厩 题目描述 农夫约翰有N(1<=N<=5000)头奶牛,每头奶牛都有一个唯一的不同于其它奶牛的编号Si,所有的奶牛都睡在一个有K个厩的谷仓中,厩的编号为0到K-1.每头 ...
- 洛谷 P2858 [USACO06FEB]奶牛零食Treats for the Cows
题目描述 FJ has purchased N (1 <= N <= 2000) yummy treats for the cows who get money for giving va ...
随机推荐
- 代码混淆防止APP被反编译指南
本文来自网易云社区 安卓App安全包含很多内容,包括混淆代码.整体Dex加固.拆分 Dex 加固.虚拟机加固等方面.事实上,这些内容也是国内近几年Android App安全保护的一种主要趋势. 混淆代 ...
- 第3章 TCP协议详解
第3章 TCP协议详解 3.1 TCP服务的特点 传输协议主要有两个:TCP协议和UDP协议,TCP协议相对于UDP协议的特点是 面向连接使用TCP协议通信的双方必须先建立连接,完成数据交换后,通信双 ...
- ConfigHelpers
--默认值可以不传 local ConfigHelpers = {} --设置物体高亮 target:设置对象 isLigth:是否高亮 seeThrough:是否穿透(默认为true,穿透) sta ...
- 三:Fair Scheduler 公平调度器
参考资料: http://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-site/FairScheduler.html http://h ...
- 如何理解*p++
后置递增运算符的优先级高于解引用运算符! *p++ 等价于 *(p++) 但是,我们*p++的求值结果不可理解为p+1指向的对象的值,而应该是p指向的对象的值. 这是由于后置++的特性引起的. *p+ ...
- 团队协作第八周个人PSP
11.3 --11.9本周例行报告 1.PSP(personal software process )个人软件过程. 类型 任务 开始时间 结束时间 中断时间 实际用时 ...
- PhotoShop基础工具 -- 移动工具
还是学点美工的东西吧, 业余爱好 比学编程还难 PS版本 : PhotoShop CS6 1. 移动工具 (1) 工具栏和属性栏 工具栏 和 属性栏 : 左侧的是工具栏, 每选中一个工具, 在菜单 ...
- a2
Alpha 冲刺报告 队名: 组长:吴晓晖 今天完成了哪些任务: 代码量300+,完成了百度地图API的引入. 展示GitHub当日代码/文档签入记录: 明日计划: 整理下这两个功能,然后补些bug ...
- 《学习OpenCV》课后习题解答6
题目:(P104) 使用cvCmp()创建一个掩码.加载一个真实的图像.使用cvsplit()将图像分割成红,绿,蓝三个单通道图像. a.找到并显示绿图. b.克隆这个绿图两次(分别命名为clone1 ...
- pfx 证书怎么打开
其实双击就能够自动运行导入向导的 不行的话使用我的办法: 单击开始--运行--里输入mmc 然后单击文件--选择添加删除管理单元--再选择添加--拉动滚动条找到证书一项,点击添加再点击完成(不用做任何 ...