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 我们讲一个悲伤的故事. ...
随机推荐
- java Switch中的case后面加上大括号({})和不加大括号的区别
java基础求真之switch 的case 后面加上大括号和不加大括号的区别. 下面给出三段代码大家看一下有什么不同以及哪段代码能够编译通过那段代码编译不能通过,为什么?(Why?) 代码片段一: i ...
- 覆写equals方法为什么需要覆写hashCode方法
覆写equals方法必须覆写hashCode方法,是JDK API上反复说明的,不过为什么要这样做呢?这两个方法之间有什么关系呢? void test() { // Person类的实例作为Map的k ...
- 02-Centos7安装部署Mirrorgate
1.以Docker方式运行 MirrorGate服务器作为docker镜像提供,因此要运行它只需在终端中执行以下命令: 注意mongo镜像要使用3.6版本,其他版本会提示版本问题. #Spinup m ...
- [C#]使用Windows Form开发的百度网盘搜索工具
BaiduDiskSearcher 用C#编写的百度网盘搜索工具(.NET4.0 & Visual Studio 2017) 功能 1.搜索任意名称的百度网盘共享文件 2.可以左键双击打开网盘 ...
- Flask_admin 笔记六 modelView的内置方法
增加model后端Flask-Admin对与之配合的数据库模型做了一些假设. 如果要实现自己的数据库后端,并且Flask-Admin的模型视图仍可按预期工作,则应注意以下事项:1) 每一个model必 ...
- linux下rsync和tar增量备份梳理
前面总结过一篇全量备份/增量备份/差异备份说明,下面介绍下linux下rsync和tar两种增量备份的操作记录: 1)rsync备份 rsync由于本身的特性,在第一次rsync备份后,以后每次都只是 ...
- Codeforces Round #504 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final)-D- Array Restoration
我们知道不满足的肯定是两边大中间小的,这样就用RMQ查询两个相同等值的区间内部最小值即可,注意边界条件 #include<bits/stdc++.h> #define x first #d ...
- beta阶段测试基本概况报告
文件地址 测试基本信息 Bitmap 测试 ...
- JAVA程序设计 实验一报告
北京电子科技学院(BESTI) 实 验 报 告 课程:Java程序设计 班级:1351 姓名:李畅宇 学号:20135129 成绩: 指导教师:娄嘉鹏 ...
- 【Deep Hash】CNNH
[AAAI 2014] Supervised Hashing via Image Representation Learning [paper] [code] Rongkai Xia , Yan Pa ...