【BZOJ 3771】Triple
Problem
Description
给出 \(n\) 个物品,第 \(i\) 个物品体积为 \(a_i\) 。
对于每个体积 \(V\) ,求选出 \(3\) 个物品,体积之和为 \(V\) 的方案总数。
选择顺序不同算同一种方案。
Range
\(n\) 保证不会读入到 \(TLE\) , \(a_i\le 4 \times 10^4\) 。
Algorithm
多项式,生成函数。
Mentality
设生成函数 \(A(x)\) 为只选择一个物品的生成函数。其中 \([x^m]A(x)\) 的系数代表了体积 \(m\) 有多少种选法。
同理设 \(B(x)\) 为选择两个相同物品的生成函数,设 \(C(x)\) 为选择三个相同物品的生成函数。
则对于最后的答案而言:
若选择的 \(3\) 个物品互不相同,则方案数为:
\]
因为根据容斥,\(A^3(x)\) 等于所有选择三个物品的方案数,\(B(x)A(x)\) 则是所有形如 \((a, a, b)\) 的方案数,由于这种方案在 \(A^3(x)\) 会出现三次,所以要乘 \(3\) ,然后对于所有 \((a,a,a)\) ,也即生成函数 \(C(x)\) 在 \(B(x)A(x)\) 中出现了 \(3\) 次,但实际上在 \(A^3(x)\) 只会被计算一次,所以还要加回 \(2\) 个来。
若选择 \(2\) 个物品,那么方案为:
\]
这个很好理解。
选择一个物品的方案自然就是 \(A(x)\) 了。
\(FFT\) 即可。
Code
#include <cmath>
#include <complex>
#include <cstdio>
#include <iostream>
using namespace std;
#define LL long long
#define cp complex<double>
#define inline __inline__ __attribute__((always_inline))
inline LL read() {
LL x = 0, w = 1;
char ch = getchar();
while (!isdigit(ch)) {
if (ch == '-') w = -1;
ch = getchar();
}
while (isdigit(ch)) {
x = (x << 3) + (x << 1) + ch - '0';
ch = getchar();
}
return x * w;
}
const int Max_n = 4e5 + 5, Ml = 1.2e5;
const double pi = acos(-1);
cp ans[Max_n], A[Max_n], B[Max_n], C[Max_n];
namespace Input {
void main() {
int n = read();
for (int i = 1, x; i <= n; i++)
x = read(), A[x] += 1, B[x * 2] += 1, C[x * 3] += 1;
}
} // namespace Input
namespace Solve {
int bit, len, rev[Max_n];
void init() {
int bit = log2(Ml + 1) + 1;
len = 1 << bit;
for (int i = 0; i < len; i++)
rev[i] = rev[i >> 1] >> 1 | ((i & 1) << (bit - 1));
}
void dft(cp *f, int t) {
for (int i = 0; i < len; i++)
if (i < rev[i]) swap(f[i], f[rev[i]]);
for (int l = 1; l < len; l <<= 1) {
cp Wn(cos(t * pi / (double)l), sin(t * pi / (double)l));
for (int i = 0; i < len; i += (l << 1)) {
cp Wnk(1, 0);
for (int k = i; k < i + l; k++, Wnk *= Wn) {
cp x = f[k], y = f[k + l] * Wnk;
f[k] = x + y, f[k + l] = x - y;
}
}
}
}
void main() {
init();
dft(A, 1), dft(B, 1), dft(C, 1);
for (int i = 0; i < len; i++) {
ans[i] = (A[i] * A[i] * A[i] - A[i] * B[i] * 3.0 + 2.0 * C[i]) / 6.0;
ans[i] += (A[i] * A[i] - B[i]) / 2.0 + A[i];
}
dft(ans, -1);
for (int i = 0; i <= Ml; i++) ans[i] /= (double)len;
for (int i = 0; i <= Ml; i++) {
LL Ans = (LL)(ans[i].real() + 0.5);
if (Ans) printf("%d %lld\n", i, Ans);
}
}
} // namespace Solve
int main() {
Input::main();
Solve::main();
}
【BZOJ 3771】Triple的更多相关文章
- 【BZOJ 3771】 3771: Triple (FFT+容斥)
3771: Triple Time Limit: 20 Sec Memory Limit: 64 MBSubmit: 547 Solved: 307 Description 我们讲一个悲伤的故事. ...
- 【BZOJ 1150】 1150: [CTSC2007]数据备份Backup (贪心+优先队列+双向链表)
1150: [CTSC2007]数据备份Backup Description 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味 的,因此你想设 ...
- Kruskal算法及其类似原理的应用——【BZOJ 3654】tree&&【BZOJ 3624】[Apio2008]免费道路
首先让我们来介绍Krukal算法,他是一种用来求解最小生成树问题的算法,首先把边按边权排序,然后贪心得从最小开始往大里取,只要那个边的两端点暂时还没有在一个联通块里,我们就把他相连,只要这个图里存在最 ...
- 【BZOJ 2957】楼房重建&&Codechef COT5 Count on a Treap&&【NOIP模拟赛】Weed 线段树的分治维护
线段树是一种作用于静态区间上的数据结构,可以高效查询连续区间和单点,类似于一种静态的分治.他最迷人的地方在于“lazy标记”,对于lazy标记一般随我们从父区间进入子区间而下传,最终给到叶子节点,但还 ...
- LCA 【bzoj 4281】 [ONTAK2015]Związek Harcerstwa Bajtockiego
[bzoj 4281] [ONTAK2015]Związek Harcerstwa Bajtockiego Description 给定一棵有n个点的无根树,相邻的点之间的距离为1,一开始你位于m点. ...
- 【BZOJ】【3771】Triple
生成函数+FFT Orz PoPoQQQ 这个题要算组合的方案,而且范围特别大……所以我们可以利用生成函数来算 生成函数是一个形式幂级数,普通生成函数可以拿来算多重集组合……好吧我承认以上是在瞎扯→_ ...
- 【BZOJ 1191】 [Apio2010]特别行动队 (斜率优化)
dsy1911: [Apio2010]特别行动队 [题目描述] 有n个数,分成连续的若干段,每段的分数为a*x^2+b*x+c(a,b,c是给出的常数),其中x为该段的各个数的和.求如何分才能使得各个 ...
- 【BZOJ 1096】 [ZJOI2007]仓库建设 (斜率优化)
1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3940 Solved: 1736 Description ...
- 【BZOJ 2132】圈地计划 && 【7.22Test】计划
两种版本的题面 Description 最近房地产商GDOI(Group of Dumbbells Or Idiots)从NOI(Nuts Old Idiots)手中得到了一块开发土地.据了解,这块土 ...
随机推荐
- 【2018寒假集训 Day2】【动态规划】维修栅栏
维修栅栏 问题描述: 小z最近当上了农场主!不过,还没有来得及庆祝,一件棘手的问题就摆在了小z的面前.农场的栅栏,由于年久失修,出现了多处破损.栅栏是由n块木板组成的,每块木板可能已经损坏也可能没有损 ...
- SpringBoot系列之集成Thymeleaf用法手册
目录 1.模板引擎 2.Thymeleaf简介 2.1).Thymeleaf定义 2.2).适用模板 3.重要知识点 3.1).th:text和th:utext 3.2).标准表达式 3.3).Thy ...
- 原生JS的移入溢出控制div的显示与隐藏
原生JS的移入溢出控制div的显示与隐藏的写法 上面的写法火狐存在兼容性
- 安装Linux基本工具
yum install wget httpd-tools vim lrzsz Linux安装wget:yum -y install wget Linux安装vim编辑器:yum -y install ...
- 在React项目中添加ESLint
1. 安装eslint npm install eslint --save-dev // 或者 yarn add eslint --dev 2. 初始化配置文件 npx eslint --init / ...
- C语言|博客作业10
问题 回答 C语言 博客作业10 这个作业要求在哪里 作业要求 我在这个课程的目标是 熟练循环语句的用法 这个作业在哪个具体方面帮助我实现目标 pta作业 参考文献 <C语言程序设计> 1 ...
- linux下创建mysql用户和数据库,并绑定
Linux下输入命令: mysql -uroot -proot123 进入mysql后输入: 查看目前有哪些数据库存在:mysql> SHOW DATABASES; 创建数据库:create s ...
- 个性的圆角.html
- Vue全家桶高仿小米商城
大家好,我是河畔一角,时隔半年再次给大家带来一门重量级的实战课程:<Vue全家桶高仿小米商城>,现在很多公司都在参与到商城的构建体系当中,因此掌握一套商城的标准开发体系非常重要:商城的开始 ...
- luogu P1566 加等式
题目描述 对于一个整数集合,我们定义"加等式"如下:集合中的某一个元素可以表示成集合内其他元素之和.如集合{1,2,3}中就有一个加等式:3=1+2,而且3=1+2 和3=2+1是 ...