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. Redis 的底层数据结构(对象)

    目前为止,我们介绍了 redis 中非常典型的五种数据结构,从 SDS 到 压缩列表,这都是 redis 最底层.最常用的数据结构,相信你也掌握的不错. 但 redis 实际存储键值对的时候,是基于对 ...

  2. linux-PAM

    PAM(Pluggable Authentication Modules)即可插拔式认证模块,一种用户级别的认证方式,它也是当前Linux服务器普遍使用的认证方式. PAM认证原理:参考资料来自htt ...

  3. 12、pytest -- 缓存:记录执行的状态

    目录 1. cacheprovider插件 1.1. --lf, --last-failed:只执行上一轮失败的用例 1.2. --ff, --failed-first:先执行上一轮失败的用例,再执行 ...

  4. scikit-learn文本特征提取之TF-IDF

    TF-IDF(term frequency–inverse document frequency)是一种用于资讯检索与文本挖掘的常用加权技术. TF-IDF是一种统计方法,用以评估一字词对于一个文件集 ...

  5. 【JavaEE】之MyBatis逆向工程的使用

    MyBatis逆向工程可以方便的从数据库中将表自动映射到JAVA POJO类,并同时生成Mapper.xml和Mapper接口,方便实用.下面介绍一下逆向工程的使用方法. 使用逆向工程,我们最好是新建 ...

  6. 【JavaEE】之MyBatis开发DAO

    在SSM框架中的DAO层就是MyBatis中的Mapper,Mapper分为两部分:Mapper接口(JAVA文件)和Mapper映射文件(XML文件).DAO开发(Mapper开发)有两种方式:原始 ...

  7. Android ListView的header footer设置visibility gone不起作用

    常用的ViewGroup,例如LinearLayout,在onMeasure方法内对每个child view执行measure前,会判断child view的visibility是否为gone.如果是 ...

  8. 关于jsp中jstl报错Can not find the tag library descriptor for "http://java.sun.com/jsp/jstl/core

    有的时候在开发jsp时,需要使用jstl时,在jsp上面引用jstl却出现错误:Can not find the tag library descriptor for "http://jav ...

  9. 小白的springboot之路(七)、事务支持

    0-前言 事务管理对于企业级应用来说必不可少,用来确保数据的完整性和一致性: 1-开启事务 spring boot支持编程式事务和声明式事务,用声明式事务即可: spring boot开启事务非常简单 ...

  10. 如何使用pandas分析金融数据

    [摘要]pandas是数据分析师分析数据最常用的三方库之一,结合matplotlib,非常强大. 首先我们收集一些数据. 从东方财富客户端导出券商信托板块2018年11月1日的基础行情和财务数据.分别 ...