【BZOJ】3771: Triple FTT+生成函数
【题意】给定n个物品,价值为$a_i$,物品价格互不相同,求选一个或两个或三个的价值为x的方案数,输出所有存在的x和对应方案数。$ai<=40000$。
【算法】生成函数+FFT
【题解】要求价值为x的方案数,就定义价值为“大小”(即指数),方案数为“元素个数”(即系数),物品为“选择项”(即多项式)。
设$f(x)$表示选择一个物品,价值为x的方案数。
虽然很容易想到$f^3(x)$,但因为不能重复选物品所以必须去重。而且不容易在$f^3(x)$中表示出选一个或两个物品。
①选择一个物品的方案数:$f$。
考虑$f^2$表示选择两个物品价值和为x的可重排列数。
去重需要减去两个物品相同的情况,设$g(x)$表示选择两个相同物品价值和为x的方案数,显然g可以直接得到。(枚举每个物品,在价值*2的系数处+1)。
因为生成函数乘积在两个物品相同的时候实际上没有排列,所以要先减再去排列。
②选择两个物品的方案数:$\frac{f^2-g}{2}$。
最后三个物品同理,设$h(x)$表示选择三个相同物品价值和为x的方案数,需要排除BAA,ABA,AAB,AAA的情况。
其中BAA,ABA,AAB相当于选择两个相同物品后再选一个物品(无论是否再相同),即$f*g$。
但这样会把AA重复减去三次,实际上只需要减去一次,所以容斥加回,即$h$。
③选择三个物品的方案数:$\frac{f^3-3*f*g+2*h}{2}$。
复杂度O(n log n)。
注意:先将f,g,h进行DFT,全部计算答案后再进行IDFT,才能保证精度。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<complex>
#include<cmath>
using namespace std;
const int maxn=;
const double PI=acos(-);
int n,ans[maxn];
complex<double>f[maxn],g[maxn],h[maxn];
namespace fft{
complex<double>o[maxn],oi[maxn];
void init(int n){
for(int k=;k<n;k++)o[k]=complex<double>(cos(*PI*k/n),sin(*PI*k/n)),oi[k]=conj(o[k]);
}
void transform(complex<double>*a,int n,complex<double>*o){
int k=;
while((<<k)<n)k++;
for(int i=;i<n;i++){
int t=;
for(int j=;j<k;j++)if(i&(<<j))t|=(<<(k-j-));
if(i<t)swap(a[i],a[t]);
}
for(int l=;l<=n;l*=){
int m=l/;
for(complex<double>*p=a;p!=a+n;p+=l){
for(int i=;i<m;i++){
complex<double>t=p[i+m]*o[n/l*i];
p[i+m]=p[i]-t;
p[i]+=t;
}
}
}
}
void dft(complex<double>*a,int n){transform(a,n,o);}
void idft(complex<double>*a,int n){transform(a,n,oi);for(int i=;i<n;i++)a[i]/=n;}
}
int main(){
scanf("%d",&n);
int mx=,t;
for(int i=;i<n;i++){
scanf("%d",&t);
f[t].real();g[t*].real(),h[t*].real();
mx=max(mx,t*);
}
n=;
while(n<*mx+)n*=;
fft::init(n);
fft::dft(f,n);fft::dft(g,n);fft::dft(h,n);
complex<double>tmp2=(),tmp3=(),tmp6=();
for(int i=;i<n;i++)f[i]=(f[i]*f[i]*f[i]-tmp3*f[i]*g[i]+tmp2*h[i])/tmp6+(f[i]*f[i]-g[i])/tmp2+f[i];
fft::idft(f,n);
for(int i=;i<n;i++)ans[i]=(int)(floor(f[i].real()+0.5));
for(int i=;i<n;i++)if(ans[i])printf("%d %d\n",i,ans[i]);
return ;
}
【BZOJ】3771: Triple FTT+生成函数的更多相关文章
- 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(FFT+容斥原理+生成函数)
[BZOJ 3771] Triple(FFT+生成函数) 题面 给出 n个物品,价值为别为\(w_i\)且各不相同,现在可以取1个.2个或3个,问每种价值和有几种情况? 分析 这种计数问题容易想到生成 ...
- BZOJ 3771: Triple [快速傅里叶变换 生成函数 容斥原理]
题意:n个物品,可以用1/2/3个不同的物品组成不同的价值,求每种价值有多少种方案(顺序不同算一种) [生成函数]: 构造这么一个多项式函数g(x),使得n次项系数为a[n]. 普通型生成函数用于解决 ...
- BZOJ 3771: Triple(生成函数 FFT)
Time Limit: 20 Sec Memory Limit: 64 MBSubmit: 911 Solved: 528[Submit][Status][Discuss] Description ...
- BZOJ 3771: Triple
Description 问所有三/二/一元组可能形成的组合. Sol FFT. 利用生成函数直接FFT一下,然后就是计算,计算的时候简单的容斥一下. 任意三个-3*两个相同的+2*全部相同的+任意两个 ...
- 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优化的话,达到 ...
随机推荐
- 蜗牛慢慢爬 LeetCode 8. String to Integer (atoi) [Difficulty: Medium]
题目 Implement atoi to convert a string to an integer. Hint: Carefully consider all possible input cas ...
- QQueue与QStack使用
版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:QQueue与QStack使用 本文地址:http://techieliang.com ...
- 在MFC中显示cmd命令行
添加函数 void InitConsoleWindow1() { ; FILE* fp; AllocConsole(); nCrt = _open_osfhandle((long)GetStdHand ...
- MySQL专题 1 分布式部署数据库同步问题 BinLog
什么是 Binlog MySQL Server 有四种类型的日志——Error Log.General Query Log.Binary Log 和 Slow Query Log. 第一个是错误日志, ...
- react-router之代码分离
概念 无需用户下载整个应用之后才能访问访问它.即边访问边下载.因此我们设计一个组件<Bundle>当用户导航到它是来动态加载组件. import loadSomething from 'b ...
- Android手机Fiddler真机抓包
Fiddler是最强大最好用的Web调试工具之一,它能记录所有客户端和服务器的http和https请求,允许用户监视,设置断点,甚至修改输入输出数据,Fiddler包含了一个强大的基于事件脚本的子系统 ...
- 第116天: Ajax运用artTemplate实现菜谱
Ajax运用artTemplate实现菜谱 一.获取接口数据 1.聚合数据API https://www.juhe.cn,在这上面找到菜谱大全数据接口文档 具体使用是这样的: key后面的数据是 ...
- Selenium遇到问题unknown error:cannot create default profile directory......
1.selenium遇到问题unknown error:cannot create default profile directory...... 2.解决方案 问题1:把驱动放入C:\Windows ...
- scoket常用函数简单介绍
scoket: 是一种抽象层,应用程序通过它来发送和接收数据,使用socket可以将应用程序添加到网络中,与处于同一网络中的其他应用程序进行通信. 简单来说,scoket提供了程序内部与外界通道的 ...
- BZOJ4974 字符串大师(kmp)
显然最短循环节长度=i-next[i],则相当于给定next数组构造字符串.然后按照kmp的过程模拟即可.虽然这看起来是一个染色问题,但是由图的特殊性,如果next=0只要贪心地选最小的就可以了,稍微 ...