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\) 个物品互不相同,则方案数为:

\[\frac{A^3(x)-3B(x)A(x)+2C(x)}{6}
\]

因为根据容斥,\(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\) 个物品,那么方案为:

\[\frac{A^2(x)-B(x)}{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的更多相关文章

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

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

  2. 【BZOJ 1150】 1150: [CTSC2007]数据备份Backup (贪心+优先队列+双向链表)

    1150: [CTSC2007]数据备份Backup Description 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味 的,因此你想设 ...

  3. Kruskal算法及其类似原理的应用——【BZOJ 3654】tree&&【BZOJ 3624】[Apio2008]免费道路

    首先让我们来介绍Krukal算法,他是一种用来求解最小生成树问题的算法,首先把边按边权排序,然后贪心得从最小开始往大里取,只要那个边的两端点暂时还没有在一个联通块里,我们就把他相连,只要这个图里存在最 ...

  4. 【BZOJ 2957】楼房重建&&Codechef COT5 Count on a Treap&&【NOIP模拟赛】Weed 线段树的分治维护

    线段树是一种作用于静态区间上的数据结构,可以高效查询连续区间和单点,类似于一种静态的分治.他最迷人的地方在于“lazy标记”,对于lazy标记一般随我们从父区间进入子区间而下传,最终给到叶子节点,但还 ...

  5. LCA 【bzoj 4281】 [ONTAK2015]Związek Harcerstwa Bajtockiego

    [bzoj 4281] [ONTAK2015]Związek Harcerstwa Bajtockiego Description 给定一棵有n个点的无根树,相邻的点之间的距离为1,一开始你位于m点. ...

  6. 【BZOJ】【3771】Triple

    生成函数+FFT Orz PoPoQQQ 这个题要算组合的方案,而且范围特别大……所以我们可以利用生成函数来算 生成函数是一个形式幂级数,普通生成函数可以拿来算多重集组合……好吧我承认以上是在瞎扯→_ ...

  7. 【BZOJ 1191】 [Apio2010]特别行动队 (斜率优化)

    dsy1911: [Apio2010]特别行动队 [题目描述] 有n个数,分成连续的若干段,每段的分数为a*x^2+b*x+c(a,b,c是给出的常数),其中x为该段的各个数的和.求如何分才能使得各个 ...

  8. 【BZOJ 1096】 [ZJOI2007]仓库建设 (斜率优化)

    1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3940  Solved: 1736 Description ...

  9. 【BZOJ 2132】圈地计划 && 【7.22Test】计划

    两种版本的题面 Description 最近房地产商GDOI(Group of Dumbbells Or Idiots)从NOI(Nuts Old Idiots)手中得到了一块开发土地.据了解,这块土 ...

随机推荐

  1. 使用Xdroid进行端口映射,出现adb server version (36) doesn't match this client (39); killing...的解决方案

    第一反应就是adb冲突了,因为Xdroid这个产品看起来就不像是给开发人员用的模拟器,因为不能选择各种版本进行适配,所以肯定自带了一个adb. whereis命令发现果然有两个adb,一个直接是安装在 ...

  2. 剑指Offer-29.最小的K个数(C++/Java)

    题目: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 分析: 最先想到的是将数组升序排列,返回前k个元素.不过排序的话效率 ...

  3. [UWP]UIElement.Clip虽然残废,但它还可以这样玩

    1. 复习一下WPF的UIElement.Clip 用了很久很久的WPF,但几乎没有主动用过它的Clip属性,我只记得它很灵活,可以裁剪出多种形状.在官方文档复习了一下,大致用法和效果如下: < ...

  4. HTML,CSS,Javascript,PHP在网站结构中扮演的“角色”

    ①HTML   在网站结构中使用来,展示网页内容的: ②CSS   在网站结构中使用来,美化页面,如字体颜色大小等: ③Javascript(JS)   在网站结构中使用来,让页面动起来,提高浏览体验 ...

  5. nginx实现内网服务唯一端口外网映射

    2.1         内网服务唯一端口外网映射 (一)       组网图 (二)       简要说明: 如标题所示,该功能可以实现内网环境下所有服务端口通过nginx的正向代理通过唯一端口映射至 ...

  6. 解决WebUploader 上传按钮按F12 才行的问题

    遇到了 WebUploader 插件的上传按钮点击无效(此时鼠标在按钮任何位置时,按钮都没变化).按F12 之后才有反应(此时鼠标在按钮任何位置时,按钮颜色都会变深) 的问题,网上查到一些答案,找到了 ...

  7. react修改端口

    react修改端口 在react官网根据文档安装好项目之后,发现新项目没有了scripst文件夹 之前版本是在scripts文件夹中的starts.js中修改 新版本修改port发现移入到了依赖里面 ...

  8. xmlhttp.readyState的值及解释

    xmlhttp.readyState的值及解释: 0:请求未初始化(还没有调用 open()). 1:请求已经建立,但是还没有发送(还没有调用 send()). 2:请求已发送,正在处理中(通常现在可 ...

  9. 重写系统自带tabbar出现的 代理错误

  10. gulp+webpack+angular1的一点小经验(第二部分webpack包起来的angular1)

    又一周过去了,项目也已经做得有点模样了.收集来一些小经验,分享给大家,有疏漏之处,还望指正,海涵. 上周整合了gulp与webpack,那么工具准备差不多了,我们就开始编码吧.编码的框架就是angul ...