题目链接

\(Description\)

  有\(n\)个物品(斧头),每个物品价值不同且只有一件,问取出一件、两件、三件物品,所有可能得到的价值和及其方案数。\((a,b),(b,a)\)算作一种方案。

\(Solution\)

  尝试用母函数去表示。\(A\)表示取一个物品对应方案数和价值的母函数,即$$A=x{v_1}+x{v_2}+x^{v_3}\ldots$$

  那么取两件就是\(A^2\),取三件是\(A^3\)。因为是组合,而这么求的是排列,所以$$Ans=A+\frac{A2}{2!}+\frac{A3}{3!}$$

  但是有问题,\(A\times A\)会出现选了同一件物品的情况,所以要减掉。考虑构造选了同一个物品两次的母函数\(B\),即\(B=x^{2v_1}+x^{2v_2}+x^{2v_3}\ldots\)

  那么取两件对应的\(Ans'=\frac{A^2-B}{2!}\)

  同理,构造取了同样物品三件的母函数\(C=x^{3v_1}+x^{3v_2}+x^{3v_3}+\ldots\)

  对于三件物品选了两件同样物品,\(A\times A\times A\ ->\ A\times B\) 可能会出现\((x,x,y),(x,y,x),(y,x,x)\)三种情况,所以减去\(3AB\)。而\(A^3\)和\(AB\)中都包含选三件同样物品的方案,多减了两次,所以要加\(2C\)。对于取三件对应的母函数\(Ans''=\frac{A^3-3AB+2C}{3!}\)

  所以$$Ans=A+\frac{A2-B}{2}+\frac{A3-3AB+2C}{6}$$

  多项式的点值表示下很多可以直接运算啊。。(并不晓得。。)

//7476kb	852ms
#include <cmath>
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
const int N=(1<<17)+5;//131072
const double PI=acos(-1); int n,rev[N];
struct Complex
{
double x,y;
Complex() {}
Complex(double x,double y):x(x),y(y) {}
Complex operator +(const Complex &a) {return Complex(x+a.x, y+a.y);}//有点纠结这换不换行。。
Complex operator -(const Complex &a) {return Complex(x-a.x, y-a.y);}
Complex operator *(const Complex &a) {return Complex(x*a.x-y*a.y, x*a.y+y*a.x);}
Complex operator *(const double &a) {return Complex(x*a, y*a);}
Complex operator /(const double &a) {return Complex(x/a, y/a);}
}A[N],B[N],C[N]; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
void FFT(Complex *a,int lim,int type)
{
for(int i=1; i<lim; ++i) if(i<rev[i]) std::swap(a[i],a[rev[i]]);
for(int i=2; i<=lim; i<<=1)
{
int mid=i>>1;
Complex Wn(cos(PI/mid),type*sin(PI/mid)),t;//2.0*PI/i
// W[0]=Complex(1,0);
// for(int j=1; j<mid; ++j) W[j]=W[j-1]*Wn;//这两行出俩错误→_→
for(int j=0; j<lim; j+=i)
{
Complex w(1,0);//不预处理更快。。是范围小的原因吗。。
for(int k=0; k<mid; ++k,w=w*Wn)
a[j+k+mid]=a[j+k]-(t=a[j+k+mid]*w),
a[j+k]=a[j+k]+t;
}
}
if(type==-1)
for(int i=0; i<lim; ++i) a[i].x/=lim;
} int main()
{
n=read(); int mx=0;
for(int v,i=1; i<=n; ++i)
mx=std::max(mx,v=read()), A[v].x=B[2*v].x=C[3*v].x=1.0;
int lim=1, L=0;
while(lim<=3*mx) lim<<=1, ++L;
for(int i=1; i<lim; ++i) rev[i]=(rev[i>>1]>>1)|((i&1)<<L-1); FFT(A,lim,1), FFT(B,lim,1), FFT(C,lim,1);
for(int i=0; i<lim; ++i)
A[i]=A[i]+(A[i]*A[i]-B[i])*0.5+(A[i]*A[i]*A[i]-A[i]*B[i]*3.0+C[i]*2.0)/6.0;
FFT(A,lim,-1);
for(int i=0; i<lim; ++i)
if((int)(A[i].x+0.5)) printf("%d %d\n",i,(int)(A[i].x+0.5));//这题还不需要longlong return 0;
}

BZOJ.3771.Triple(母函数 FFT 容斥)的更多相关文章

  1. spoj TSUM - Triple Sums fft+容斥

    题目链接 首先忽略 i < j < k这个条件.那么我们构造多项式$$A(x) = \sum_{1现在我们考虑容斥:1. $ (\sum_{}x)^3 = \sum_{}x^3 + 3\s ...

  2. BZOJ 3771: Triple(生成函数 FFT)

    Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 911  Solved: 528[Submit][Status][Discuss] Description ...

  3. SPOJ - TSUM 母函数+FFT+容斥

    题意:n个数,任取三个加起来,问每个可能的结果的方案数. 题解:构造母函数ABC,比如现在有 1 2 3 三个数.则 其中B表示同一个数加两次,C表示用三次.然后考虑去重. A^3表示可重复地拿三个. ...

  4. [BZOJ 3771] Triple(FFT+容斥原理+生成函数)

    [BZOJ 3771] Triple(FFT+生成函数) 题面 给出 n个物品,价值为别为\(w_i\)且各不相同,现在可以取1个.2个或3个,问每种价值和有几种情况? 分析 这种计数问题容易想到生成 ...

  5. 【BZOJ 3771】 3771: Triple (FFT+容斥)

    3771: Triple Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 547  Solved: 307 Description 我们讲一个悲伤的故事. ...

  6. BZOJ 3771: Triple(FFT+容斥)

    题面 Description 我们讲一个悲伤的故事. 从前有一个贫穷的樵夫在河边砍柴. 这时候河里出现了一个水神,夺过了他的斧头,说: "这把斧头,是不是你的?" 樵夫一看:&qu ...

  7. BZOJ 3771 Triple FFT+容斥原理

    解析: 这东西其实就是指数型母函数? 所以刚开始读入的值我们都把它前面的系数置为1. 然后其实就是个多项式乘法了. 最大范围显然是读入的值中的最大值乘三,对于本题的话是12W? 用FFT优化的话,达到 ...

  8. BZOJ 3771: Triple

    Description 问所有三/二/一元组可能形成的组合. Sol FFT. 利用生成函数直接FFT一下,然后就是计算,计算的时候简单的容斥一下. 任意三个-3*两个相同的+2*全部相同的+任意两个 ...

  9. HDU 4609 3-idiots FFT+容斥

    一点吐槽:我看网上很多分析,都是在分析这个题的时候,讲了半天的FFT,其实我感觉更多的把FFT当工具用就好了 分析:这个题如果数据小,统计两个相加为 x 的个数这一步骤(这个步骤其实就是求卷积啊),完 ...

随机推荐

  1. Perl6 必应抓取(2):最终版

    use HTTP::UserAgent; use URI::Encode; Firefox/52.0>); my $bing_url = 'http://cn.bing.com/search?q ...

  2. 【原创】Linux环境下的图形系统和AMD R600显卡编程(1)——Linux环境下的图形系统简介

    Linux/Unix环境下最早的图形系统是Xorg图形系统,Xorg图形系统通过扩展的方式以适应显卡和桌面图形发展的需要,然而随着软硬件的发展,特别是嵌入式系统的发展,Xorg显得庞大而落后.开源社区 ...

  3. DenseNet笔记

    一.DenseNet的优点 减轻梯度消失问题 加强特征的传递 充分利用特征 减少了参数量 二.网络结构公式 对于每一个DenseBlock中的每一个层, [x0,x1,…,xl-1]表示将0到l-1层 ...

  4. 使用脚本实现killproc的功能

    在shell提示符号下输入type killproc,会发现killproc实在 /sbin/目录下,通过man killproc可以查看这个脚本(姑且这么称为脚本)的用法,现在,把这个脚本的实现过程 ...

  5. vue总结07 常用插件

    插件 开发插件 插件通常会为 Vue 添加全局功能.插件的范围没有限制——一般有下面几种: 添加全局方法或者属性,如: vue-custom-element 添加全局资源:指令/过滤器/过渡等,如 v ...

  6. 洛谷P1168中位数

    传送门啦 基本思想就是二分寻找答案,然后用树状数组去维护有几个比这个二分出来的值大,然后就没有了: 数据要离散,这个好像用map也可以,但是不会: 那怎么离散呢? 我们先把a数组读入并复制给s数组,然 ...

  7. 规范命名CSS

    作者:词晖链接:https://www.zhihu.com/question/19586885/answer/48933504来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出 ...

  8. WiFi无线连接真机进行Appium自动化测试方法

    有时需要测试APP 产品的耗电问题,但用自动化又面临了一个USB接电脑供电的问题,从而导致计算出来的功耗与手动跑,存在有很大的误差,因此可使用wifi无线连接到手机进行自动化测试,解决功耗问题. 前提 ...

  9. C# 图片和二进制之间的转换

    1> 图片转二进制  public byte[] GetPictureData(string imagepath){/**/////根据图片文件的路径使用文件流打开,并保存为byte[] Fil ...

  10. fedora常见问题和解决方案

    fedora作为linux主流发行版之一,大部分功能还是很赞的.只是在美观性和其他一些细节上还是需要手工调整才有更加体验. 以下解决方案,使用fedora20+gnome3环境 eclipse界面难看 ...