Luogu 2000 拯救世界
从胡小兔的博客那里过来的,简单记一下生成函数。
生成函数
数列$\{1, 1, 1, 1, \cdots\}$的生成函数是$f(x) = 1 + x + x^2 + x^3 + \cdots$,根据等比数列求和公式,可以得到$f(x) = \frac{1}{1 - x}$。
把两边分别平方,得到
$$\frac{1}{(1 - x)^2} = (1 + x + x^2 + x^3 + x^4 + \cdots)^2 = 1 + 2x + 3x^2 + 4x^3 + \cdots$$
相当于数列$\{1, 2, 3, 4, 5, \cdots \}$的生成函数。
两边三次方,得到
$$\frac{1}{(1 - x)^3} = 1 + 3x + 6x^2 + 10x^3 + \cdots$$
发现数列$\sum_{i = 0}^{\infty}\binom{i + k - 1}{k - 1}x^i$的生成函数是$\frac{1}{(1 - x)^k}$。
而数列$\sum_{i = 0}^{\infty}x^i[i \mod k == 0]$的生成函数是$\frac{1}{1 - x^k}$。
本题解法
把限制条件看成数列,第一个限制条件相当于数列$\{1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, \cdots \}$,而第二个限制条件则相当于有限长数列$\{1, 1, 1, 1, 1, 1, 1, 1, 1\}$,……,所有的限制条件都可以这样子类推出来。
把这个数列写成生成函数,第个限制条件的第$i$项系数可以看成是这一项取$i$个的方法,把这十个生成函数乘起来之后得到的生成函数的第$i$项就相当于一共取了$i$项的方案数。
最后乘起来得到了$\frac{1}{(1 - x)^5}$,对应了数列$\sum_{i = 0}^{\infty}\binom{i + 4}{4}x^i$的第$n$项,即$\frac{(n + 1)(n + 2)(n + 3)(n + 4)}{24}$。
然后就是一个高精了,因为$n$的位数很多,所以乘法的时候需要写$fft$。
Code:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
typedef double db; const int N = 2e6 + ;
const db Pi = acos(-1.0); int lim, pos[N];
char str[N]; struct Cpx {
db x, y; inline Cpx (db _x = , db _y = ) {
x = _x, y = _y;
} friend Cpx operator + (const Cpx u, const Cpx v) {
return Cpx(u.x + v.x, u.y + v.y);
} friend Cpx operator - (const Cpx u, const Cpx v) {
return Cpx(u.x - v.x, u.y - v.y);
} friend Cpx operator * (const Cpx u, const Cpx v) {
return Cpx(u.x * v.x - u.y * v.y, u.x * v.y + v.x * u.y);
} } a[N], b[N]; inline void prework(int len) {
int l = ;
for (lim = ; lim < len; lim <<= , ++l);
for (int i = ; i < lim; i++)
pos[i] = (pos[i >> ] >> ) | ((i & ) << (l - ));
} inline void fft(Cpx *c, int opt) {
for (int i = ; i < lim; i++)
if (i < pos[i]) swap(c[i], c[pos[i]]);
for (int i = ; i < lim; i <<= ) {
Cpx wn(cos(Pi / i), opt * sin(Pi / i));
for (int len = i << , j = ; j < lim; j += len) {
Cpx w(, );
for (int k = ; k < i; k++, w = w * wn) {
Cpx x = c[j + k], y = w * c[j + k + i];
c[j + k] = x + y, c[j + k + i] = x - y;
}
}
}
} struct BigInt {
int len, s[N]; inline void init() {
len = ;
memset(s, , sizeof(s));
} inline void readIn() {
scanf("%s", str);
len = strlen(str);
for (int i = ; i < len; i++) s[i] = str[len - i - ] - '';
} inline void print() {
if (!len) putchar('');
else {
for (int i = len - ; i >= ; i--) printf("%d", s[i]);
}
printf("\n");
} friend BigInt operator + (const BigInt &x, const int &y) {
BigInt res = x;
res.s[] += y;
for (int i = ; i < res.len; i++) {
if (i == res.len - ) {
if (res.s[i] >= ) ++res.len;
else break;
}
res.s[i + ] += res.s[i] / , res.s[i] %= ;
}
for (; res.s[res.len - ] == && res.len > ; --res.len);
return res;
} friend BigInt operator * (const BigInt &x, const BigInt &y) {
prework(x.len + y.len - );
for (int i = ; i < lim; i++) a[i] = b[i] = Cpx(, );
for (int i = ; i < x.len; i++) a[i].x = x.s[i];
for (int i = ; i < y.len; i++) b[i].x = y.s[i];
fft(a, ), fft(b, );
for (int i = ; i < lim; i++) a[i] = a[i] * b[i];
fft(a, -); BigInt res;
res.init();
res.len = x.len + y.len - ;
for (int i = ; i < res.len; i++) res.s[i] = int(a[i].x / lim + 0.5); for (int i = ; i < res.len; i++) {
if (i == res.len - ) {
if (res.s[i] >= ) ++res.len;
else break;
}
res.s[i + ] += res.s[i] / , res.s[i] %= ;
}
for (; res.s[res.len - ] == && res.len > ; --res.len); return res;
} friend BigInt operator / (const BigInt &x, const int y) {
BigInt res;
res.init();
int rest = ;
for (int i = x.len - ; i >= ; i--) {
rest = rest * + x.s[i];
if (rest >= y) res.s[res.len++] = rest / y, rest %= y;
else if (res.len) res.s[res.len++] = ;
}
for (int i = ; i < res.len / ; i++) swap(res.s[i], res.s[res.len - - i]);
return res;
} } n; int main() {
#ifndef ONLINE_JUDGE
freopen("Sample.txt", "r", stdin);
#endif n.readIn();
// n.print(); BigInt n1 = n + , n2 = n + , n3 = n + , n4 = n + ;
// n1.print(), n2.print(), n3.print(), n4.print(); BigInt ans = n1 * n2 * n3 * n4;
// ans.print(); ans = ans / ;
ans.print();
return ;
}
Luogu 2000 拯救世界的更多相关文章
- luogu P2000 拯救世界
嘟嘟嘟 题目有点坑,要你求的多少大阵指的是召唤kkk的大阵数 * lzn的大阵数,不是相加. 看到这个限制条件,显然要用生成函数推一推. 比如第一个条件"金神石的块数必须是6的倍数" ...
- luogu P2000 拯救世界 生成函数_麦克劳林展开_python
模板题. 将所有的多项式按等比数列求和公式将生成函数压缩,相乘后麦克劳林展开即可. Code: n=int(input()) print((n+1)*(n+2)*(n+3)*(n+4)//24)
- [题解] Luogu P2000 拯救世界
生成函数板子题...... 要写高精,还要NTT优化......异常dl 这个并不难想啊...... 一次召唤会涉及到\(10\)个因素,全部写出来,然后乘起来就得到了答案的生成函数,输出\(n\)次 ...
- 洛谷P2000 拯救世界(生成函数)
题面 题目链接 Sol 生成函数入门题 至多为\(k\)就是\(\frac{1-x^{k+1}}{1-x}\) \(k\)的倍数就是\(\frac{1}{1-x^k}\) 化简完了就只剩下一个\(\f ...
- 【洛谷】P2000 拯救世界
题解 小迪的blog : https://www.cnblogs.com/RabbitHu/p/9178645.html 请大家点推荐并在sigongzi的评论下面点支持谢谢! 掌握了小迪生成函数的有 ...
- 清北学堂模拟赛d7t6 拯救世界
分析:如果题目中没有环的话就是一道裸的最长路的题目,一旦有环每个城市就会被救多次火了.把有向有环图变成有向无环图只需要tarjan一边就可以了. #include <bits/stdc++.h& ...
- [LGP2000] 拯救世界
6的倍数 1/(1-x^6) 最多9块 (1-x^10)/(1-x) 最多5块 (1-x^6)/(1-x) 4的倍数 1/(1-x^4) 最多7块 (1-x^8)/(1-x) 2的倍数 1/(1-x^ ...
- Luogu2000 拯救世界
题目链接:戳我 生成函数的入门题吧. 我们可以把条件限制转化为生成函数,然后用第i项的系数来表示一共使用n块石头的方案个数. (你问我为什么?你可以自己演算一下,或者去看大佬的博客-->这里面讲 ...
- [洛谷P2000 拯救世界]
生成函数版题. 考虑对于这些条件写出\(OGF\) \(1 + x^6 + x^{12} + x^{18}..... = \frac{1}{1 - x^6}\) \(1 + x + x ^ 2 + x ...
随机推荐
- celery制作定时任务
celery参考地址:http://docs.celeryproject.org/en/latest/userguide/periodic-tasks.html#starting-the-schedu ...
- Zen Coding改名Emmet-功能更智能化
早在2009年,谢尔盖Chikuyonok写了一篇文章,提出了一种新的编写HTML和CSS代码的方式.这一革命性的插件,被称为zen coding,多年来已帮助许多开发人员,现在已达到一个新的水平. ...
- Data_Structure02-线性表
一.PTA实验作业 本周要求挑3道题目写设计思路.调试过程.设计思路用伪代码描述. 1.顺序表选择一题(6-2,6-3,7-1选一题),代码必须用顺序结构抽象数据类型封装 2.单链表选择一题(6-1不 ...
- shelve模块(超级好用~!)
''' python中的shelve模块,可以提供一些简单的数据操作 他和python中的dbm很相似. 区别如下: 都是以键值对的形式保存数据,不过在shelve模块中, key必须为字符串,而值可 ...
- 04:Sysbench压测-innodb_flush_log_at_trx_commit,sync_binlog参数对性能的影响
目录 sysbench压测-innodb_flush_log_at_trx_commit,sync_binlog参数对性能的影响 一.OLTP测试前准备 二.MySQL 数据落盘的过程 三.参数说明 ...
- SQL Server Management Studio (SSMS)
最新的SQLServer数据库已经不集成SQL Server Management Studio需要单独下载安装. https://docs.microsoft.com/zh-cn/sql/ssms/ ...
- JavaScript中的可枚举属性与不可枚举属性
在JavaScript中,对象的属性分为可枚举和不可枚举之分,它们是由属性的enumerable值决定的.可枚举性决定了这个属性能否被for…in查找遍历到. 一.怎么判断属性是否可枚举 js中基本包 ...
- 【转】C#事件、委托、回调的用法与区别
原文地址:http://blog.csdn.net/huang9012/article/details/38753305 事件包括:事件发送者.事件接收者和事件处理程序.关于事件,我们首要知道的是事件 ...
- 【合】C#线程
浅谈ThreadPool 线程池 地址:https://www.cnblogs.com/xugang/archive/2010/04/20/1716042.html 相关概念: 线程池可以看做容纳线程 ...
- idea展现目录清晰方式