原题地址:https://open.kattis.com/problems/aplusb

FFT代码参考kuangbin的博客:http://www.cnblogs.com/kuangbin/archive/2013/07/24/3210565.html

A+B Problem

Given N integers in the range [−50000,50000], how many ways are there to pick three

integers ai, aj, ak, such that i, j, k are pairwise distinct and ai+aj=ak? Two ways

are different if their ordered triples (i,j,k)of indices are different.

Input

The first line of input consists of a single integer N

(1≤N≤200000). The next line consists of N space-separated integers a1,a2,…,aN

Output

Output an integer representing the number of ways.

Sample Input 1

                     Sample Output 1

4

1 2 3 4

4

Sample Input 2

                     Sample Output 2

6

1 1 3 3 4 6

10

Author(s): Tung Kam Chuen

Source: Hong Kong Regional Online Preliminary 2016

题意:给一个数列,从中选三个数 ai, aj, ak,使得ai+aj=ak,问共有多少组( i, j, k)满足条件。

其实就是FFT。

注意一下a数组的数据范围,a[i]可能为负数,所有a[i]+50000,把负数转化为正数处理;

如果数组里有0,先把0删掉,最后特殊处理。

把a数组转化成num数组,num[i]表示i出现的次数。

然后num数组和num数组卷积,得到新的num数组。

num数组意义:num[x]表示使ai+aj=x,(i,j)的取法有多少种。

#include <algorithm>
#include <cstring>
#include <string.h>
#include <iostream>
#include <list>
#include <map>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#include <cstdio>
#include <cmath> #define LL long long
#define N 200005
#define INF 0x3ffffff using namespace std; const double PI = acos(-1.0); struct Complex // 复数
{
double r,i;
Complex(double _r = ,double _i = )
{
r = _r; i = _i;
}
Complex operator +(const Complex &b)
{
return Complex(r+b.r,i+b.i);
}
Complex operator -(const Complex &b)
{
return Complex(r-b.r,i-b.i);
}
Complex operator *(const Complex &b)
{
return Complex(r*b.r-i*b.i,r*b.i+i*b.r);
}
}; void change(Complex y[],int len) // 二进制平摊反转置换 O(logn)
{
int i,j,k;
for(i = , j = len/;i < len-;i++)
{
if(i < j)swap(y[i],y[j]);
k = len/;
while( j >= k)
{
j -= k;
k /= ;
}
if(j < k)j += k;
}
}
void fft(Complex y[],int len,int on) //DFT和FFT
{
change(y,len);
for(int h = ;h <= len;h <<= )
{
Complex wn(cos(-on**PI/h),sin(-on**PI/h));
for(int j = ;j < len;j += h)
{
Complex w(,);
for(int k = j;k < j+h/;k++)
{
Complex u = y[k];
Complex t = w*y[k+h/];
y[k] = u+t;
y[k+h/] = u-t;
w = w*wn;
}
}
}
if(on == -)
for(int i = ;i < len;i++)
y[i].r /= len;
} const int M =; // a数组所有元素+M,使a[i]>=0
const int MAXN = ; Complex x1[MAXN];
int a[MAXN/]; //原数组
long long num[MAXN]; //利用FFT得到的数组
long long tt[MAXN]; //统计数组每个元素出现个数 int main()
{
int n=; // n表示除了0之外数组元素个数
int tot;
scanf("%d",&tot);
memset(num,,sizeof(num));
memset(tt,,sizeof(tt)); int cnt0=; //cnt0 统计0的个数
int aa; for(int i = ;i < tot;i++)
{
scanf("%d",&aa);
if(aa==) {cnt0++;continue;} //先把0全删掉,最后特殊考虑0
else a[n]=aa;
num[a[n]+M]++;
tt[a[n]+M]++;
n++;
} sort(a,a+n);
int len1 = a[n-]+M+;
int len = ; while( len < *len1 ) len <<= ; for(int i = ;i < len1;i++){
x1[i] = Complex(num[i],);
}
for(int i = len1;i < len;i++){
x1[i] =Complex(,);
}
fft(x1,len,); for(int i = ;i < len;i++){
x1[i] = x1[i]*x1[i];
}
fft(x1,len,-); for(int i = ;i < len;i++){
num[i] = (long long)(x1[i].r+0.5);
} len = *(a[n-]+M); for(int i = ;i < n;i++) //删掉ai+ai的情况
num[a[i]+a[i]+*M]--;
/*
for(int i = 0;i < len;i++){
if(num[i]) cout<<i-2*M<<' '<<num[i]<<endl;
}
*/
long long ret= ; int l=a[n-]+M; for(int i = ;i <=l; i++) //ai,aj,ak都不为0的情况
{
if(tt[i]) ret+=(long long)(num[i+M]*tt[i]);
} ret+=(long long)(num[*M]*cnt0); // ai+aj=0的情况 if(cnt0!=)
{
if(cnt0>=) { //ai,aj,ak都为0的情况
long long tmp=;
tmp*=(long long)(cnt0);
tmp*=(long long)(cnt0-);
tmp*=(long long)(cnt0-);
ret+=tmp;
}
for(int i = ;i <=l; i++)
{
if(tt[i]>=){ // x+0=x的情况
long long tmp=(long long)cnt0;
tmp*=(long long)(tt[i]);
tmp*=(long long)(tt[i]-);
ret+=tmp*;
}
}
} printf("%lld\n",ret); return ;
}

2016 acm香港网络赛 A题. A+B Problem (FFT)的更多相关文章

  1. 2016 acm香港网络赛 C题. Classrooms(贪心)

    原题网址:https://open.kattis.com/problems/classrooms Classrooms The new semester is about to begin, and ...

  2. 2016 acm香港网络赛 B题. Boxes

    原题网址:https://open.kattis.com/problems/boxes Boxes There are N boxes, indexed by a number from 1 to N ...

  3. 2016 acm香港网络赛 F题. Crazy Driver(水题)

    原题网址:https://open.kattis.com/problems/driver Crazy Driver In the Linear City, there are N gates arra ...

  4. hihoCoder #1388 : Periodic Signal ( 2016 acm 北京网络赛 F题)

    时间限制:5000ms 单点时限:5000ms 内存限制:256MB 描述 Profess X is an expert in signal processing. He has a device w ...

  5. hdu 5881 Tea (2016 acm 青岛网络赛)

    原题地址:http://acm.hdu.edu.cn/showproblem.php?pid=5881 Tea Time Limit: 3000/1000 MS (Java/Others)    Me ...

  6. HDU 5901 Count primes (2016 acm 沈阳网络赛)

    原题地址:http://acm.hdu.edu.cn/showproblem.php?pid=5901 题意:输入n,输出n以内质数个数 模板题,模板我看不懂,只是存代码用. 官方题解链接:https ...

  7. 2013 acm 长沙网络赛 G题 素数+枚举 Goldbach

    题目 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3856 先预处理求出两个素数的和与积,然后枚举n-prime和n/pr ...

  8. 2018 ACM南京网络赛H题Set解题报告

    题目描述 给定\(n\)个数$a_i$,起初第\(i\)个数在第\(i\)个集合.有三种操作(共\(m\)次): 1 $u$ $v$ 将第$u$个数和第$v$个数所在集合合并 2 $u$ 将第$u$个 ...

  9. ACM-ICPC 2019南昌网络赛F题 Megumi With String

    ACM-ICPC 南昌网络赛F题 Megumi With String 题目描述 给一个长度为\(l\)的字符串\(S\),和关于\(x\)的\(k\)次多项式\(G[x]\).当一个字符串\(str ...

随机推荐

  1. Go -- 读取文件内容

    Golang 的文件读取方法很多,刚上手时不知道怎么选择,所以贴在此处便后速查. 一次性读取 小文件推荐一次性读取,这样程序更简单,而且速度最快. 代码如下: func ReadAll(filePth ...

  2. [Android Traffic] 调整定时更新的频率(C2DM与退避算法)

    转载自: http://blog.csdn.net/kesenhoo/article/details/7395253 Minimizing the Effect of Regular Updates[ ...

  3. git reset revert区别

    git revert HEAD~1 撤销倒数第二次提交,并将这次操作作为一个新提交添加到log里,之前的提交历史不变,是撤销某次提交 git reset,直接回退到指定版本 git reset --s ...

  4. 6、Python模块

    最常用的两个模块: os    #可以允许python调用执行系统命令,如shell sys    #处理与python程序本身的事情   Python自带200多个常用模块 Python官网收集了2 ...

  5. 修改Tomcat标题栏内容

    你是否遇到过在一个OS任务栏中同时打开多个Tomcat启动程序窗口,这种情况下你会无法区分具体是哪个窗口启动哪个程序,以下方式可以实现Bat启动程序标题栏自定义. 打开Tomcat的Bin目录中,打开 ...

  6. 倍福TwinCAT(贝福Beckhoff)基础教程 松下伺服驱动器报错 21.0怎么办

    编码器通讯断线异常保护,一般就是通讯线松动或者受干扰(最难以排查的情况是,我接了六套驱动器和伺服,比如J0的线是随便做的,其他五套都是西门子的合格网线,我运行程序的时候,J0如果单关节运动没任何问题, ...

  7. Location配置与ReWrite语法

    1 Location语法规则 1.1 Location规则 语法规则: location [=|~|~*|^~] /uri/ {… } 首先匹配 =,其次匹配^~,其次是按文件中顺序的正则匹配,最后是 ...

  8. 创建你的第一个ionic+cordova应用(1)

    前面我们安装了前端的神器webstorm11,体验到了强大的开发体验,接着我们来安装ionic 必备: Node.js (npm安装工具) 百度下载 官网下载  注:如果官网新版不能安装请用百度下载0 ...

  9. kettle入门(七) 之kettle增量方案(一)全量比对取增量-依据唯一标示

    引: ods有个project表来自于上游系统,数据量不大 十几万,下游系统须要此数据,而且须要每天提供截止当天的增量数据 要求每条数据给出数据变化时间及标示,即数据若是插入 有插入时间和插入标示 若 ...

  10. Window 7 开 WIFI做热点

    cmd下两个命令即可: C:\Users\lyx>netsh wlan set hostednetwork mode=allow ssid=ACE-PC key=12345678承载网络模式已设 ...