BZOJ 3771: Triple(生成函数 FFT)
Time Limit: 20 Sec Memory Limit: 64 MB
Submit: 911 Solved: 528
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
4
5
6
7
Sample Output
5 1
6 1
7 1
9 1
10 1
11 2
12 1
13 1
15 1
16 1
17 1
18 1
样例解释
11有两种方案是4+7和5+6,其他损失值都有唯一方案,例如4=4,5=5,10=4+6,18=5+6+7.
HINT
所有数据满足:Ai<=40000
Source
应该不难看出是生成函数
我们用$A(x) = a + bx^1 + cx^2 + \dots $表示价值为$1$的方案为$a$,价值为$2$的方案为$b$
那么很显然的思路就是:$A(x) + \frac{A(x) * A(x)}{2!} + \frac{A(x) * A(x) * A(x)}{3!}$
但是题目中要求了每种斧子只能拿一次,这样会多计算重复拿的一部分
因此我们考虑用容斥的方法将他们减去
定义$B(x) = x ^ i$表示价值为$i$的拿了两把的方案数
$C(x) = x ^ i$表示价值为$i$的拿了三把的方案数
拿两把斧子时会计算到$(x, x)$这种情况,所以拿两把时应该为$\frac{A(x) * A(x) - B(x)}{2!}$
拿三把时有些复杂
我们需要减去$(x, x, x)$和$(x, y, y)$这两种情况
第一种情况就是$C(x)$
第二种情况可以通过$A(x)* B(x)$计算得到,但此时也计算上了$(x, x, x)$这种情况
$(x, y, y)$有三种组合排列方式,所以要乘$3$,但$(x, x, x)$只有一种排列方式,所以最终统计答案时要加上$2 * C(x)$
最终的答案就是
$A + \frac{A * A - B}{2!} + \frac{A * A * A - 3 * A * B + 2C}{3!}$
多项式乘法可以用NTT,不过模数会炸998244353
看到大佬们都用FFT A了,那我就偷个懒喽
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
//#include<iostream>
const double pi = acos(-);
using namespace std;
const int MAXN = ;
inline int read() {
char c = getchar(); int x = , f = ;
while(c < '' || c > '') {if(c == '-') f = -; c = getchar();}
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * f;
}
struct complex {
double x, y;
complex(double xx = , double yy = ) {x = xx, y = yy;}
complex operator + (const complex &rhs) {
return complex(x + rhs.x, y + rhs.y);
}
complex operator - (const complex &rhs) {
return complex(x - rhs.x, y - rhs.y);
}
complex operator * (const complex &rhs) {
return complex(x * rhs.x - y * rhs.y, x * rhs.y + y * rhs.x);
}
complex operator * (const double &rhs) {
return complex(x * rhs, y * rhs);
}
complex operator / (const double &rhs) {
return complex(x / rhs, y / rhs);
}
}A[MAXN], B[MAXN], C[MAXN];
int val, n, N, L, len, r[MAXN];
void FFT(complex *A, int type) {
for(int i = ; i < N; i++) if(i < r[i]) swap(A[i], A[r[i]]);
for(int mid = ; mid < N; mid <<= ) {
complex Wn(cos(pi / mid), type * sin(pi / mid));
for(int j = ; j < N; j += (mid << )) {
complex w = complex(, );
for(int i = ; i < mid; i++, w = w * Wn) {
complex x = A[j + i], y = w * A[j + i + mid];
A[j + i] = x + y;
A[j + i + mid] = x - y;
}
}
}
if(type == -) {
for(int i = ; i < N; i++)
A[i].x /= N;
}
}
void print(complex *a) {
for(int i = ; i < N; i++)
printf("%d %lf %lf\n", i, a[i].x, a[i].y);
}
int main() {
#ifdef WIN32
freopen("a.in", "r", stdin);
freopen("b.out", "w", stdout);
#endif
n = read();
for(int i = ; i <= n; i++)
val = read(),
A[val].x = ,
B[ * val].x = ,
C[ * val].x = ,
len = max( * val, len);
len = len + ;//tag
for(N = ; N <= len; N <<= , L++);
for(int i = ; i < N; i++)
r[i] = (r[i >> ] >> ) | ((i & ) << (L - )); FFT(C, );
FFT(A, );
FFT(B, );
for(int i = ; i < N; i++)
A[i] = A[i] + (A[i] * A[i] - B[i]) / 2.0 + (A[i] * A[i] * A[i] - A[i] * B[i] * 3.0 + C[i] * 2.0) / 6.0;
FFT(A, -); for(int i = ; i < N; i++) {
long long cur = (long long )(A[i].x + 0.5);
if(cur)
printf("%d %lld\n", i, cur);
}
return ;
}
BZOJ 3771: Triple(生成函数 FFT)的更多相关文章
- BZOJ.3771.Triple(母函数 FFT 容斥)
题目链接 \(Description\) 有\(n\)个物品(斧头),每个物品价值不同且只有一件,问取出一件.两件.三件物品,所有可能得到的价值和及其方案数.\((a,b),(b,a)\)算作一种方案 ...
- [BZOJ 3771] Triple(FFT+容斥原理+生成函数)
[BZOJ 3771] Triple(FFT+生成函数) 题面 给出 n个物品,价值为别为\(w_i\)且各不相同,现在可以取1个.2个或3个,问每种价值和有几种情况? 分析 这种计数问题容易想到生成 ...
- bzoj 3771 Triple FFT 生成函数+容斥
Triple Time Limit: 20 Sec Memory Limit: 64 MBSubmit: 847 Solved: 482[Submit][Status][Discuss] Desc ...
- bzoj 3771: Triple【生成函数+FFT+容斥原理】
瞎搞居然1A,真是吃鲸 n的范围只有聪明人能看见--建议读题3遍 首先看计数就想到生成函数,列出多项式A(x),然后分别考虑123 对于选一个的直接计数即可: 对于选两个的,\( A(x)^2 \), ...
- BZOJ 3771: Triple [快速傅里叶变换 生成函数 容斥原理]
题意:n个物品,可以用1/2/3个不同的物品组成不同的价值,求每种价值有多少种方案(顺序不同算一种) [生成函数]: 构造这么一个多项式函数g(x),使得n次项系数为a[n]. 普通型生成函数用于解决 ...
- bzoj 3771 Triple——FFT
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3771 把方案作为系数.值作为指数,两项相乘就是系数相乘.指数相加,符合意义. 考虑去重.先自 ...
- bzoj 3771 Triple —— FFT
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3771 令多项式的系数是方案数,次数是值: 设 a(x) 为一个物品的多项式,即 a[w[i] ...
- BZOJ 3771 Triple FFT+容斥原理
解析: 这东西其实就是指数型母函数? 所以刚开始读入的值我们都把它前面的系数置为1. 然后其实就是个多项式乘法了. 最大范围显然是读入的值中的最大值乘三,对于本题的话是12W? 用FFT优化的话,达到 ...
- BZOJ 3771 Triple ——FFT
直接暴力卷积+统计就可以了. 去重比较复杂. 其实也不复杂,抄吧! 反正AC了. #include <map> #include <cmath> #include <qu ...
随机推荐
- 动态赋值poster,无法显示
vue操作video的poster属性时,动态给poster赋值,在chrome下是无法显示的 解决办法 在赋值后,找到video元素.load()下就会看到封面图了
- intellij-maven-imports-have-broken-classpath
公司自己搭得maven私服,然后使用git下载 公司mvn的依赖包时候,报错: 之后再idea里面发现依赖的jar包 有红色的错误信息,提示 maven imports have broken cla ...
- 如何有效防止API的重放攻击(转自阿里云)
API重放攻击(Replay Attacks)又称重播攻击.回放攻击,这种攻击会不断恶意或欺诈性地重复一个有效的API请求.攻击者利用网络监听或者其他方式盗取API请求,进行一定的处理后,再把它重新发 ...
- JsonPath教程
1. 介绍 类似于XPath在xml文档中的定位,JsonPath表达式通常是用来路径检索或设置Json的.其表达式可以接受“dot–notation”和“bracket–notation”格式,例如 ...
- scanf函数读取缓冲区数据的问题
标准I\O的缓冲类型 标准I\O根据不同的应用需求,提供了全缓冲.行缓冲.无缓冲三种缓冲方式. 全缓冲:只有当划定的缓冲区被填满或者数据读取至末尾时,才开始执行I\O操作(执行系统提供的read\wr ...
- C#配置IIS搭建网站的工具类
public class IISWorker { public static string HostName = "localhost"; /// <summary> ...
- 鉴定JavaScript中的数据类型
众所周知,JavaScript是一门弱类型的语言,但是这并不代表JavaScript中没有数据类型.JavaScript中常见的数据类型有string.number.object等等,通常我们使用ty ...
- JavaScript的DOM_操作内容
一.innerText 属性 <script type="text/javascript"> window.onload = function(){ var box = ...
- api的使用机制:继承、实例化、实现(继承)配置、实例(参数化)配置、机制管理模块
api的使用机制:继承.实例化.实现(继承)配置.实例(参数化)配置.机制管理模块 facade模式.管理模块
- hdu1579 Function Run Fun(深搜+记忆化)
版权声明:本文为博主原创文章.未经博主同意不得转载.vasttian https://blog.csdn.net/u012860063/article/details/37076755 转载请注明出处 ...