SPOJ TSUM Triple Sums(FFT + 容斥)

时间:2022-09-21 23:48:43

题目

Source

http://www.spoj.com/problems/TSUM/

Description

You're given a sequence s of N distinct integers.
Consider all the possible sums of three integers from the sequence at three different indicies.
For each obtainable sum output the number of different triples of indicies that generate it.

Constraints:
N <= 40000, |si| <= 20000

Input

The first line of input contains a single integer N.
Each of the next N lines contain an element of s.

Output

Print the solution for each possible sum in the following format:
sum_value : number_of_triples

Smaller sum values should be printed first.

Sample Input

5
-1
2
3
0
5

Sample Output

1 : 1
2 : 1
4 : 2
5 : 1
6 : 1
7 : 2
8 : 1
10 : 1

分析

题目大概说给n个数,从中选出三个数求和,问能到的各个和分别有几种取法能够得到?

这题很容易。。因为刚做过HDU4609。。
就是根据初始的序列构造出三个一样的多项式,指数表示数字,系数表示该数字出现次数。
然后三个多项式的乘积相当于表示有顺序有放回地取数字的结果。这个用FFT求。

不过这不是组合,可以用容斥原理去掉那些取法重复的。
即减去3种两个取同一边的情况,这个也用FFT求;然后加上三个都取同一边的情况,for一遍即可求;最后除以3的阶乘。

注意到时间好像比较紧,所以我做了些处理,比如三个多项式相乘直接三个点值相乘、避免重复的DFT过程。。
。。然后没想到居然暂时列第二,与第一同时间:

SPOJ TSUM Triple Sums(FFT + 容斥)

代码

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define MAXN 131072
const double PI=acos(-1.0); struct Complex{
double real,imag;
Complex(double _real=0,double _imag=0):real(_real),imag(_imag){}
Complex operator+(const Complex &cp) const{
return Complex(real+cp.real,imag+cp.imag);
}
Complex operator-(const Complex &cp) const{
return Complex(real-cp.real,imag-cp.imag);
}
Complex operator*(const Complex &cp) const{
return Complex(real*cp.real-imag*cp.imag,real*cp.imag+cp.real*imag);
}
void setValue(double _real=0,double _imag=0){
real=_real; imag=_imag;
}
}; int len;
Complex wn[MAXN+1],wn_anti[MAXN+1]; void FFT(Complex y[],int op){
for(int i=1,j=len>>1,k; i<len-1; ++i){
if(i<j) swap(y[i],y[j]);
k=len>>1;
while(j>=k){
j-=k;
k>>=1;
}
if(j<k) j+=k;
}
for(int h=2; h<=len; h<<=1){
Complex Wn=(op==1?wn[h]:wn_anti[h]);
for(int i=0; i<len; i+=h){
Complex W(1,0);
for(int j=i; j<i+(h>>1); ++j){
Complex u=y[j],t=W*y[j+(h>>1)];
y[j]=u+t;
y[j+(h>>1)]=u-t;
W=W*Wn;
}
}
}
if(op==-1){
for(int i=0; i<len; ++i) y[i].real/=len;
}
} Complex A[MAXN],B[MAXN];
double ans[MAXN];
int s[40100],cnt[80100]; int main(){
for(int i=0; i<=MAXN; ++i){
wn[i].setValue(cos(2.0*PI/i),sin(2.0*PI/i));
wn_anti[i].setValue(wn[i].real,-wn[i].imag);
} int n;
scanf("%d",&n);
for(int i=0; i<n; ++i){
scanf("%d",&s[i]);
s[i]+=20000;
++cnt[s[i]];
} len=MAXN; for(int i=0; i<=40000; ++i){
B[i].setValue(cnt[i]);
}
FFT(B,1);
for(int i=0; i<MAXN; ++i){
A[i]=B[i]*B[i]*B[i];
}
FFT(A,-1);
for(int i=0; i<MAXN; ++i){
ans[i]=A[i].real;
} memset(cnt,0,sizeof(cnt));
for(int i=0; i<n; ++i){
++cnt[s[i]+s[i]];
}
for(int i=0; i<=80000; ++i){
A[i].setValue(cnt[i]);
}
for(int i=80001; i<MAXN; ++i){
A[i].setValue(0);
}
FFT(A,1);
for(int i=0; i<MAXN; ++i){
A[i]=A[i]*B[i];
}
FFT(A,-1);
for(int i=0; i<MAXN; ++i){
ans[i]-=3*A[i].real;
} for(int i=0; i<n; ++i){
++ans[s[i]+s[i]+s[i]];
} for(int i=0; i<MAXN; ++i){
long long tmp=(long long)(ans[i]/6.0+0.5);
if(tmp){
printf("%d : %lld\n",i-60000,tmp);
}
}
return 0;
}

SPOJ TSUM Triple Sums(FFT + 容斥)的更多相关文章

  1. spoj TSUM - Triple Sums fft&plus;容斥

    题目链接 首先忽略 i < j < k这个条件.那么我们构造多项式$$A(x) = \sum_{1现在我们考虑容斥:1. $ (\sum_{}x)^3 = \sum_{}x^3 + 3\s ...

  2. BZOJ&period;3771&period;Triple&lpar;母函数 FFT 容斥&rpar;

    题目链接 \(Description\) 有\(n\)个物品(斧头),每个物品价值不同且只有一件,问取出一件.两件.三件物品,所有可能得到的价值和及其方案数.\((a,b),(b,a)\)算作一种方案 ...

  3. 【BZOJ 3771】 3771&colon; Triple &lpar;FFT&plus;容斥&rpar;

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

  4. BZOJ 3771&colon; Triple&lpar;FFT&plus;容斥&rpar;

    题面 Description 我们讲一个悲伤的故事. 从前有一个贫穷的樵夫在河边砍柴. 这时候河里出现了一个水神,夺过了他的斧头,说: "这把斧头,是不是你的?" 樵夫一看:&qu ...

  5. HDU 4609 3-idiots FFT&plus;容斥

    一点吐槽:我看网上很多分析,都是在分析这个题的时候,讲了半天的FFT,其实我感觉更多的把FFT当工具用就好了 分析:这个题如果数据小,统计两个相加为 x 的个数这一步骤(这个步骤其实就是求卷积啊),完 ...

  6. Spoj 8372 Triple Sums

    题意:给你n个数字,对于任意s,s满足\(s=u_i+u_j+u_k,i<j<k\),要求出所有的s和对应满足条件的i,j,k的方案数 Solution: 构造一个函数:\(A(x)=\s ...

  7. 【XSY2753】Lcm 分治 FWT FFT 容斥

    题目描述 给你\(n,k\),要你选一些互不相同的正整数,满足这些数的\(lcm\)为\(n\),且这些数的和为\(k\)的倍数. 求选择的方案数.对\(232792561\)取模. \(n\leq ...

  8. SPOJ - TSUM 母函数&plus;FFT&plus;容斥

    题意:n个数,任取三个加起来,问每个可能的结果的方案数. 题解:构造母函数ABC,比如现在有 1 2 3 三个数.则 其中B表示同一个数加两次,C表示用三次.然后考虑去重. A^3表示可重复地拿三个. ...

  9. SPOJ:Triple Sums(母函数&plus;FFT)

    You're given a sequence s of N distinct integers.Consider all the possible sums of three integers fr ...

随机推荐

  1. lr中switch的应用

    Action() { char *time; int i,j,length; time=lr_eval_string("{testtime}"); lr_error_message ...

  2. 基于Theano的DNN框架Blocks使用简要总结

    Blocks官方代码地址:https://github.com/mila-udem/blocks Blocks是加拿大Montreal大学Bengio实验室牵头开发的基于Python的神经网络模型框架 ...

  3. 电脑知识--Windows一片

    .com档 Dos可执行命令文件,一般小于64kb, .com文件包括程序的一个绝对映像.就是说,为了执行程序准确的处理器指令和内存中的数据.Ms-Dos通过直接把该映像从文件复制到内存. 而 载入. ...

  4. 打开IIS的快捷键

    [windows键+R]→在运行界面输入“inetmgr”→点击回车键,即可以出现IIS界面

  5. &period;NET MD5 加密

    using System; using System.Security.Cryptography; using System.Text; namespace Md5Demo { /// <sum ...

  6. 随便说说sequelize的问题

    最近在做的项目频繁的修改数据库让人感觉很烦躁,sequelize在执行sync的时候只会重新创建表,如果原先有数据只能直接删除,但是这样显然是不行的,因为数据不能就这么消失了吧. 所以必须要migra ...

  7. NGINX Docs &vert; Load Balancing Apache Tomcat Servers with NGINX Open Source and NGINX Plus

    NGINX Docs | Load Balancing Apache Tomcat Servers with NGINX Open Source and NGINX Plushttps://docs. ...

  8. Django 数据传递

    在前面的访问数据库中,我们是这样来插入数据的: [root@localhost web]$ cat web/urls.py urlpatterns = patterns('', .... url(r' ...

  9. 中南多校对抗赛 第三场 E

    E:Eulerian Flight Tour 题意: 给你一张无向图,要你给这个图加边使得其形成一个欧拉回路 题解: 首先使得所有节点的度都为偶数,然后将这个图联通起来 对于度为奇数的点,将将他和他的 ...

  10. Qt 串口类QSerialPort 使用笔记

    Qt 串口类QSerialPort 使用笔记 虽然现在大多数的家用PC机上已经不提供RS232接口了.但是由于RS232串口操作简单.通讯可靠,在工业领域中仍然有大量的应用.Qt以前的版本中,没有提供 ...