BZOJ3771 Triple(FFT+容斥原理)
思路比较直观。设A(x)=Σxai。先把只选一种的统计进去。然后考虑选两种,这个直接A(x)自己卷起来就好了,要去掉选同一种的情况然后除以2。现在得到了选两种的每种权值的方案数,再把这个卷上A(x)。得到这个后考虑去重,其中重复的就是选了两个相同的和另外一个,那么再把选两个相同的生成函数搞出来卷上A,减掉选三个相同的。把这个东西减掉之后再除以3。说了半天也不知道在说啥,总之是容斥原理很基础的应用。
有些卡精度,用long double才过,可能是我写丑了。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
#define N 270000
#define double long double
const double PI=3.14159265358979324;
struct complex
{
double x,y;
complex operator +(const complex&a) const
{
return (complex){x+a.x,y+a.y};
}
complex operator -(const complex&a) const
{
return (complex){x-a.x,y-a.y};
}
complex operator *(const complex&a) const
{
return (complex){x*a.x-y*a.y,x*a.y+y*a.x};
}
}w[N],v[N],u[N];
int n,m,t,a[N],r[N];
long long f[N];
void DFT(int n,complex *a,int p)
{
for (int i=;i<n;i++) if (i<r[i]) swap(a[i],a[r[i]]);
for (int i=;i<=n;i<<=)
{
complex wn=(complex){cos(*PI/i),p*sin(*PI/i)};
for (int j=;j<n;j+=i)
{
complex w=(complex){,};
for (int k=j;k<j+(i>>);k++,w=w*wn)
{
complex x=a[k],y=w*a[k+(i>>)];
a[k]=x+y,a[k+(i>>)]=x-y;
}
}
}
}
void mul(int n,complex *a,complex *b)
{
for (int i=;i<n;i++) r[i]=(r[i>>]>>)|(i&)*(n>>);
for (int i=;i<n;i++) a[i].y=a[i].x-b[i].x,a[i].x=a[i].x+b[i].x;
DFT(n,a,);
for (int i=;i<n;i++) a[i]=a[i]*a[i];
DFT(n,a,-);
for (int i=;i<n;i++) a[i].x=a[i].x/n/;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj3771.in","r",stdin);
freopen("bzoj3771.out","w",stdout);
const char LL[]="%d %I64d\n";
#else
const char LL[]="%d %lld\n";
#endif
n=read();
for (int i=;i<=n;i++)
{
int x=read();
m=max(m,x);
w[x].x=v[x].x=f[x]=a[x]=;
}
t=;while (t<=(m<<)) t<<=;
mul(t,w,v);
for (int i=;i<=m;i++) if (a[i]) w[i<<].x--;
for (int i=;i<=m*;i++) f[i]+=w[i].x=(int)(w[i].x/+0.5);
for (int i=m*+;i<t;i++) w[i].x=w[i].y=;
for (int i=;i<=m;i++) v[i].x=a[i],v[i].y=;
for (int i=m+;i<t;i++) v[i].x=v[i].y=;
t=;while (t<=m*) t<<=;
mul(t,w,v);
for (int i=;i<t;i++) u[i].x=(i&)?:a[i>>];
for (int i=;i<=m;i++) v[i].x=a[i],v[i].y=;
for (int i=m+;i<t;i++) v[i].x=,v[i].y=;
mul(t,u,v);
for (int i=;i<=m;i++) if (a[i]) u[i*].x--;
for (int i=;i<=m*;i++) f[i]+=(long long)((w[i].x-u[i].x)/+0.5);
for (int i=;i<=m*;i++)
if (f[i]) printf(LL,i,f[i]);
return ;
}
BZOJ3771 Triple(FFT+容斥原理)的更多相关文章
- 【bzoj3771】Triple FFT+容斥原理
题目描述 樵夫的每一把斧头都有一个价值,不同斧头的价值不同.总损失就是丢掉的斧头价值和. 他想对于每个可能的总损失,计算有几种可能的方案. 注意:如果水神拿走了两把斧头a和b,(a,b)和(b,a)视 ...
- [BZOJ 3771] Triple(FFT+容斥原理+生成函数)
[BZOJ 3771] Triple(FFT+生成函数) 题面 给出 n个物品,价值为别为\(w_i\)且各不相同,现在可以取1个.2个或3个,问每种价值和有几种情况? 分析 这种计数问题容易想到生成 ...
- BZOJ 3771 Triple FFT+容斥原理
解析: 这东西其实就是指数型母函数? 所以刚开始读入的值我们都把它前面的系数置为1. 然后其实就是个多项式乘法了. 最大范围显然是读入的值中的最大值乘三,对于本题的话是12W? 用FFT优化的话,达到 ...
- 【BZOJ3771】Triple 生成函数 FFT 容斥原理
题目大意 有\(n\)把斧头,不同斧头的价值都不同且都是\([0,m]\)的整数.你可以选\(1\)~\(3\)把斧头,总价值为这三把斧头的价值之和.请你对于每种可能的总价值,求出有多少种选择方案. ...
- 2018.12.31 bzoj3771: Triple(生成函数+fft+容斥原理)
传送门 生成函数经典题. 题意简述:给出nnn个数,可以从中选1/2/31/2/31/2/3个,问所有可能的和对应的方案数. 思路: 令A(x),B(x),C(x)A(x),B(x),C(x)A(x) ...
- SPOJ Triple Sums(FFT+容斥原理)
# include <cstdio> # include <cstring> # include <cstdlib> # include <iostream& ...
- bzoj3771: Triple(容斥+生成函数+FFT)
传送门 咳咳忘了容斥了-- 设\(A(x)\)为斧头的生成函数,其中第\(x^i\)项的系数为价值为\(i\)的斧头个数,那么\(A(x)+A^2(x)+A^3(x)\)就是答案(于是信心满满的打了一 ...
- bzoj 3771: Triple【生成函数+FFT+容斥原理】
瞎搞居然1A,真是吃鲸 n的范围只有聪明人能看见--建议读题3遍 首先看计数就想到生成函数,列出多项式A(x),然后分别考虑123 对于选一个的直接计数即可: 对于选两个的,\( A(x)^2 \), ...
- 【BZOJ 3771】 3771: Triple (FFT+容斥)
3771: Triple Time Limit: 20 Sec Memory Limit: 64 MBSubmit: 547 Solved: 307 Description 我们讲一个悲伤的故事. ...
随机推荐
- android ImageLoader加载本地图片的工具类
import android.widget.ImageView; import com.nostra13.universalimageloader.core.ImageLoader; /** * 异步 ...
- JavaScript设计模式 - 订阅发布模式(观察者模式)
var Event = (function() { var global = this, Event, _default = 'default'; Event = function() { var _ ...
- Apache与Nginx
Apache与Nginx的优缺点比较 --- 1.nginx相对于apache的优点: 轻量级,同样起web 服务,比apache占用更少的内存及资源 抗并发,nginx 处理请求是异步非阻塞的 ...
- SQL Server 索引中include的魅力(具有包含性列的索引)(转载)
开文之前首先要讲讲几个概念 [覆盖查询] 当索引包含查询引用的所有列时,它通常称为“覆盖查询”. [索引覆盖] 如果返回的数据列就包含于索引的键值中,或者包含于索引的键值+聚集索引的键值中,那么就不 ...
- Luogu P1514 引水入城
我承认我有点懒(洛谷已经发过题解了,但我发誓要坚持写博客) 这道题坑了我3天…… 首先一看就与染色问题类似,果断BFS(写DFS炸了) 先将最上面(靠近水)的一行全部扔进队列里,做一遍BFS 再对最下 ...
- WPF 录屏软件研发心得及思路分享(已结束开发)
最近由于工程需要开始研发基于Windows的自动录屏软件,很多细节很多功能需要处理,毕竟一个完美的录屏软件不是你随随便便就可以写出来的.首先参考了大部分的录屏软件,在研发的过程中遇到了很多的问题:比如 ...
- 运维中的日志切割操作梳理(Logrotate/python/shell脚本实现)
对于Linux系统安全来说,日志文件是极其重要的工具.不知为何,我发现很多运维同学的服务器上都运行着一些诸如每天切分Nginx日志之类的CRON脚本,大家似乎遗忘了Logrotate,争相发明自己的轮 ...
- windows如何查看电脑开关机记录
如何查看电脑开关机记录 (一)如果你只是想查看一下,从昨天关机到今天开机之间有没有人使用我的计算机,在“开始”菜单的运行”中输入“eventvwr.msc”,或者是按下"开始菜单" ...
- visual studio 2013的使用和单元测试
Visual Studio 2013 是一个先进的开发解决方案,各种规模的团队通过它均可设计和创建引人注目的应用程序.Visual Studio 13在新功能包括C#和VB编译器和IDE支持完全基于. ...
- Week7阅读笔记
关于银弹: Brooks在他最著名的这篇文章里指出,在软件开发过程里是没有万能的终杀性武器的,只有各种方法综合运用,才是解决之道.而各种声称如何如何神奇的理论或方法,都不是能杀死“软件危机”这头人狼的 ...