链接:http://acmoj.shu.edu.cn/problem/533/

题意:求一个序列中,有多少三元组(其中元素不重复)在任意的排列下能构成等差数列。

分析:等差数列:\(A_j-A_i=A_k-A_j\),即\(2A_j=A_i+A_k\),枚举\(A_i+A_j\)的所有情况对应的个数,再扫一遍求解。

先统计出每个数对应的出现次数,FFT计算出和的组合情况。但是要减去\(A_i+A_i\)得到的结果以及\(A_i+A_j\)以及\(A_j+A_i\)重复的计算。

现在对于数\(A_j\),假设\(cnt=2*A_j\)的系数,当然cnt中要减去\(A_j\)本身和一个值与\(A_j\)相等的数组合而成的情况。枚举完这个数以后,把这个数从序列中抹去,因为这个数对结果做出的贡献已经计算,之后的统计中该数以及该数对结果的贡献不能重复计算。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN = 1e5 + 10;
const double PI = acos(-1.0);
struct Complex{
double x, y;
inline Complex operator+(const Complex b) const {
return (Complex){x +b.x,y + b.y};
}
inline Complex operator-(const Complex b) const {
return (Complex){x -b.x,y - b.y};
}
inline Complex operator*(const Complex b) const {
return (Complex){x *b.x -y * b.y,x * b.y + y * b.x};
}
} va[MAXN * 2 + MAXN / 2], vb[MAXN * 2 + MAXN / 2];
int lenth = 1, rev[MAXN * 2 + MAXN / 2];
int N, M; // f 和 g 的数量
//f g和 的系数
// 卷积结果
// 大数乘积
int f[MAXN],g[MAXN];
vector<LL> conv;
vector<LL> multi;
void debug(){for(int i=0;i<conv.size();++i) cout<<conv[i]<<" ";cout<<endl;}
//f g
void init()
{
int tim = 0;
lenth = 1;
conv.clear(), multi.clear();
memset(va, 0, sizeof va);
memset(vb, 0, sizeof vb);
while (lenth <= N + M - 2)
lenth <<= 1, tim++;
for (int i = 0; i < lenth; i++)
rev[i] = (rev[i >> 1] >> 1) + ((i & 1) << (tim - 1));
}
void FFT(Complex *A, const int fla)
{
for (int i = 0; i < lenth; i++){
if (i < rev[i]){
swap(A[i], A[rev[i]]);
}
}
for (int i = 1; i < lenth; i <<= 1){
const Complex w = (Complex){cos(PI / i), fla * sin(PI / i)};
for (int j = 0; j < lenth; j += (i << 1)){
Complex K = (Complex){1, 0};
for (int k = 0; k < i; k++, K = K * w){
const Complex x = A[j + k], y = K * A[j + k + i];
A[j + k] = x + y;
A[j + k + i] = x - y;
}
}
}
}
void getConv(){ //求多项式
init();
for (int i = 0; i < N; i++)
va[i].x = f[i];
for (int i = 0; i < M; i++)
vb[i].x = g[i];
FFT(va, 1), FFT(vb, 1);
for (int i = 0; i < lenth; i++)
va[i] = va[i] * vb[i];
FFT(va, -1);
for (int i = 0; i <= N + M - 2; i++)
conv.push_back((LL)(va[i].x / lenth + 0.5));
} void getMulti() //求A*B
{
getConv();
multi = conv;
reverse(multi.begin(), multi.end());
multi.push_back(0);
int sz = multi.size();
for (int i = 0; i < sz - 1; i++){
multi[i + 1] += multi[i] / 10;
multi[i] %= 10;
}
while (!multi.back() && multi.size() > 1)
multi.pop_back();
reverse(multi.begin(), multi.end());
} int a[MAXN];
int cnt[MAXN];
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int T; scanf("%d",&T);
while(T--){
int n; scanf("%d",&n);
int mx = -1;
memset(cnt,0,sizeof(cnt));
for(int i =1;i<=n;++i){
scanf("%d",&a[i]);
mx = max(mx,a[i]);
cnt[a[i]]++;
}
N = M = mx+1;
for(int i=0;i<N;++i){
f[i] = g[i] = cnt[i];
}
getConv();
int sz = conv.size();
for(int i=1;i<=n;++i){
conv[a[i]*2]--;
}
for(int i=0;i<sz;++i){
conv[i]>>=1;
}
LL res=0;
//debug();
//sort(a+1,a+n+1);
for(int i=1;i<=n;++i){
if(2*a[i]>=sz) continue;
LL tmp = conv[2*a[i]];
tmp -= cnt[a[i]]-1; //减去由自己构成的
conv[2*a[i]] -= cnt[a[i]]-1; //将Ai对结果的贡献抹去
cnt[a[i]]--; //将Ai从原序列中抹去
res += tmp;
}
printf("%lld\n",res);
}
return 0;
}

SHUOJ Arithmetic Sequence (FFT)的更多相关文章

  1. hdu 5400 Arithmetic Sequence

    http://acm.hdu.edu.cn/showproblem.php?pid=5400 Arithmetic Sequence Time Limit: 4000/2000 MS (Java/Ot ...

  2. hdu 5400 Arithmetic Sequence(模拟)

    Problem Description A sequence b1,b2,⋯,bn are called (d1,d2)-arithmetic sequence ≤i≤n) such that ≤j& ...

  3. Arithmetic Sequence(dp)

    Arithmetic Sequence Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 51  Solved: 19[Submit][Status][We ...

  4. [Swift]LeetCode1027. 最长等差数列 | Longest Arithmetic Sequence

    Given an array A of integers, return the length of the longest arithmetic subsequence in A. Recall t ...

  5. (模拟)Arithmetic Sequence -- HDU -- 5400

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=5400 Time Limit: 4000/2000 MS (Java/Others)    Memory ...

  6. HZAU 21——Arithmetic Sequence——————【暴力 or dp】

    Arithmetic Sequence Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 1810  Solved: 311[Submit][Status] ...

  7. 华中农业大学第四届程序设计大赛网络同步赛-1020: Arithmetic Sequence,题挺好的,考思路;

    1020: Arithmetic Sequence Time Limit: 1 Sec  Memory Limit: 128 MB Submit:  ->打开链接<- Descriptio ...

  8. LeetCode 1027. Longest Arithmetic Sequence

    原题链接在这里:https://leetcode.com/problems/longest-arithmetic-sequence/ 题目: Given an array A of integers, ...

  9. 【leetcode】1027. Longest Arithmetic Sequence

    题目如下: Given an array A of integers, return the length of the longest arithmetic subsequence in A. Re ...

随机推荐

  1. 一老掉牙的故事、是一个阿Q还是另一道曙光

       几年前曾经看到过这个故事,当时以为自己要怎样怎样!可结果似乎不那么美好!    几年人生美好广景,几年依然碌碌无为,不沉着.不冷静.不务实.不圆滑.不老练.不勇敢.不勤劳,关键不聪明,无毅力.着 ...

  2. 常用的jQuery前端技巧收集

    调试时巧用console.log(),这比用alert()方便多了. jquery易错点:元素拼接的时候,元素还未添加到DOM,就用该预添加元素操作. ajax动态获取的数据,还没有装载html元素, ...

  3. servlet和jsp中间的交互

    jsp本质上也是一个servlet, 所有的jsp页面最终会编译成一个servlet 1. jsp访问servlet jsp访问servlet比较简单通过get, post的方式直接访问servlet ...

  4. List remove及ConcurrentModificationException异常

    参考:http://blog.csdn.net/androidboy365/article/details/50540202/ 解决方案 // 1 使用Iterator提供的remove方法,用于删除 ...

  5. dbForge mysql数据库比对

    Comparison选项卡,新建一个表结构比较, (将source库的表结构变化应用到target库) 下面示例中,source用positec_uat,     target用positec_pro ...

  6. Hibernate与数据库的触发器协同工作

    Hibernate 与数据库中的触发器协同工作时, 会造成两类问题 1触发器使 Session 的缓存中的持久化对象与数据库中对应的数据不一致:触发器运行在数据库中, 它执行的操作对 Session ...

  7. ITIL信息技术基础架构库

    服务是什么? 服务是向客户提供价值的一种手段,使客户不用承担特定的成本和风险就可以获得所期望的结果 PS:运维工作中需要实时反馈 RACI RACI是一个相对直观的模型,用以明确组织变革过程中的各个角 ...

  8. Code Forces 645A Amity Assessment

    A. Amity Assessment time limit per test2 seconds memory limit per test256 megabytes inputstandard in ...

  9. 简单安装与配置mysql数据库(绿色版)

    目录 绿色版下载 mysql绿色版(5.7版本的安装与配置) 绿色版下载: mysql官网下载地址:https://www.oracle.com/index.html mysql绿色版(5.7版本的安 ...

  10. Nagle's Algorithm and TCP_NODELAY

    w非全尺寸分组的发送条件 HTTP The Definitive Guide TCP has a data stream interface that permits applications to ...