题目描述

樵夫的每一把斧头都有一个价值,不同斧头的价值不同。总损失就是丢掉的斧头价值和。
他想对于每个可能的总损失,计算有几种可能的方案。
注意:如果水神拿走了两把斧头a和b,(a,b)和(b,a)视为一种方案。拿走三把斧头时,(a,b,c),(b,c,a),(c,a,b),(c,b,a),(b,a,c),(a,c,b)视为一种方案。

输入

第一行是整数N,表示有N把斧头。
接下来n行升序输入N个数字Ai,表示每把斧头的价值。

输出

若干行,按升序对于所有可能的总损失输出一行x y,x为损失值,y为方案数。

样例输入

4
4
5
6
7

样例输出

4 1
5 1
6 1
7 1
9 1
10 1
11 2
12 1
13 1
15 1
16 1
17 1
18 1


题解

FFT+容斥原理

一个数的方案数$f(x)$,就是原序列的生成函数(初学时理解为桶 = =)。

两个数的方案数为$(f*f)(x)$,但其中包含了两次使用了同一个数的方案数$g(x)=f(2x)$,而其余的方案统计了两次,所以方案数为$\frac 12(f*f-g)(x)$。

三个数的方案数为$(f*f*f)(x)$,但其中包含了三次使用了同一个数的方案数$h(x)=f(3x)$,包含了使用了两次同一个数,另一个数不同的方案数$(f*g-h)(x)*3$(里面减掉$h$是因为三次使用同一个数的方案数被重复计算,而乘3是因为在$(f*f*f)(x)$中计算了3次),而其余的方案统计了,所以方案数为$\frac 16((f*f*f-3*f*g+2*h)(x))$。

最后数值不为0的就是答案。

#include <cstdio>
#include <cmath>
#include <algorithm>
#define N 1 << 19
#define pi acos(-1)
using namespace std;
typedef long long ll;
struct data
{double x , y;data() {x = y = 0;}data(double x0 , double y0) {x = x0 , y = y0;}data operator+(const data a)const {return data(x + a.x , y + a.y);}data operator-(const data a)const {return data(x - a.x , y - a.y);}data operator*(const data a)const {return data(x * a.x - y * a.y , x * a.y + y * a.x);}
}a[N] , b[N] , c[N] , d[N] , e[N];
int f[N];
void fft(data *a , int n , int flag)
{int i , j , k;for(i = k = 0 ; i < n ; i ++ ){if(i > k) swap(a[i] , a[k]);for(j = (n >> 1) ; (k ^= j) < j ; j >>= 1);}for(k = 2 ; k <= n ; k <<= 1){data wn(cos(2 * pi * flag / k) , sin(2 * pi * flag / k));for(i = 0 ; i < n ; i += k){data t , w(1 , 0);for(j = i ; j < i + (k >> 1) ; j ++ , w = w * wn)t = w * a[j + (k >> 1)] , a[j + (k >> 1)] = a[j] - t , a[j] = a[j] + t;}}if(flag == -1)for(i = 0 ; i < n ; i ++ )a[i].x /= n;
}
int main()
{int n , i , t , m = 0 , len;scanf("%d" , &n);while(n -- ) scanf("%d" , &t) , a[t].x ++ , b[t * 2].x ++ , c[t * 3].x ++ , d[t].x ++ , e[t * 2].x ++ , f[t] ++ ;m = t * 3;for(len = 1 ; len < m ; len <<= 1);fft(a , len , 1) , fft(b , len ,  1);for(i = 0 ; i < len ; i ++ ) b[i] = b[i] * a[i] , a[i] = a[i] * a[i] * a[i];fft(a , len , -1) , fft(b , len , -1);fft(d , len , 1);for(i = 0 ; i < len ; i ++ ) d[i] = d[i] * d[i];fft(d , len , -1);for(i = 1 ; i <= m ; i ++ )if((ll)(a[i].x - 3 * b[i].x + 2 * c[i].x + 0.5) / 6 + (ll)(d[i].x - e[i].x + 0.5) / 2 + f[i])printf("%d %lld\n" , i , (ll)(a[i].x - 3 * b[i].x + 2 * c[i].x + 0.5) / 6 + (ll)(d[i].x - e[i].x + 0.5) / 2 + f[i]);return 0;
}

转载于:https://www.cnblogs.com/GXZlegend/p/7413487.html

【bzoj3771】Triple FFT+容斥原理相关推荐

  1. bzoj3771 Triple

    3771: Triple Time Limit: 20 Sec   Memory Limit: 64 MB Submit: 313   Solved: 174 [ Submit][ Status][ ...

  2. BZOJ3771 Triple(FFT+容斥原理)

    思路比较直观.设A(x)=Σxai.先把只选一种的统计进去.然后考虑选两种,这个直接A(x)自己卷起来就好了,要去掉选同一种的情况然后除以2.现在得到了选两种的每种权值的方案数,再把这个卷上A(x). ...

  3. 解题报告(二)C、(darkBZOJ 3771)Triple(生成函数 + FFT + 容斥原理)(3)

    繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量题解和代码,题目难度不一定按照题号排序,我会在每道题后面加上题目难度指数(1∼51 \sim 51∼5),以模板题难度 11 ...

  4. bzoj3771:Triple

    传送门 生成函数 设生成函数\(f(x)\),可以将系数定为选的方案数,指数定为代价 那么 \[ f(x)=\sum_{i=1}^{n}x^{w_i} \] 然后答案就是\(f^3(x)+f^2(x) ...

  5. bzoj3771: Triple

    码完这题有一种很爽很放松的感觉...155行...2.5个中午+1个早上真的值,毕竟我没mod题解啊!!! 这题一开始想的时候就想到了补0价值的斧头,然后FFT三次,结果发现有什么重复取一个啊,取的顺 ...

  6. 【AGC005F】Many Easy Problems FFT 容斥原理

    题目大意 给你一棵树,有\(n\)个点.还给你了一个整数\(k\). 设\(S\)为树上某些点的集合,定义\(f(S)\)为最小的包含\(S\)的联通子图的大小. \(n\)个点选\(k\)个点一共有 ...

  7. 【BZOJ3771】Triple

    刚学的FFT..证明好玄乎啊 根据mjs大佬的原话,FFT这种东西不需要理解,背了模板就好 先贴题 链接:BZOJ3771 Triple 题意:从n个数中选出1,2或3个数求和,询问组成每个和的方案数 ...

  8. Lucas定理:线性求所有逆元的方法

    Miskcoo's Space,版权所有丨如未注明,均为原创 转载请注明转自:http://blog.miskcoo.com/2014/09/linear-find-all-invert 主要绕过费马 ...

  9. #3771. Triple 生成函数 + FFT + 容斥

    传送门 文章目录 题意: 思路: 题意: 思路: 注意到这个题是求若干个数的组合数,(a,b),(b,a)(a,b),(b,a)(a,b),(b,a)视为一种方案,所以我们考虑生成一个普通型生成函数. ...

最新文章

  1. phonegap android,Phonegap 3不适用于Android Studio
  2. CSS-in-JS的权衡
  3. slice,substring,substr的区别
  4. Python练习:tkinter(1)
  5. python闭包、装饰器
  6. 正方形个数(二维点哈希)
  7. MATLAB观察日志(part1)--求极限
  8. word List 13
  9. 将数组的列表结构转成树结构
  10. cp: 略过目录XXXXXX
  11. js+html空间数据编码问题--以姓名为例(代码设涉及文件读取,文本数字提取,特别是文本x,y坐标的提取)
  12. ViewPager Kotlin 教程入门
  13. Mac环境配置MySQL(详细)
  14. html 表格横向排列,excel表格数据如何实现横向排列-Excel表格怎样把多列横向数据按照顺序改为纵向排列......
  15. 领英使用手册—领英linkedin发送消息和InMail使用的方法技巧
  16. ZigBee网络数据传递流程_蓝牙、WIFI、Zigbee谁更适合物联网,各有哪些优缺点?...
  17. 电源设计基础笔记:DC-DC与LDO电路
  18. BackTrack安装
  19. 【matlab郭彦甫课程答案】
  20. 小程序真机调试代码包太大

热门文章

  1. ASP.NET Calendar 控件
  2. Mesos:一个开源的分布式弹性资源管理系统
  3. 防止IFRAME页被嵌套
  4. 杭电 hdu 1003
  5. MVCAction接收数据方式
  6. Mybatis批量添加对象List
  7. Spark Streaming实时计算框架介绍
  8. SQL update select语句
  9. dedecms 实现分页填写页码直接跳转到分页 【dedecms】
  10. Android优化五:布局优化