Arithmetic Progressions

Given N integers A1, A2, …. AN, Dexter wants to know how many ways he can choose three numbers such that they are three consecutive terms of an arithmetic progression.

Meaning that, how many triplets (i, j, k) are there such that 1 ≤ i < j < k ≤ Nand Aj - Ai = Ak - Aj.

So the triplets (2, 5, 8), (10, 8, 6), (3, 3, 3) are valid as they are three consecutive terms of an arithmetic
progression. But the triplets (2, 5, 7), (10, 6, 8) are not.

Input

First line of the input contains an integer N (3 ≤ N ≤ 100000). Then the following line contains N space separated integers A1, A2, …, AN and they have values between 1 and 30000 (inclusive).

Output

Output the number of ways to choose a triplet such that they are three consecutive terms of an arithmetic progression.

Example

Input:
10
3 5 3 6 3 4 10 4 5 2 Output:
9

Explanation

The followings are all 9 ways to choose a triplet

1 : (i, j, k) = (1, 3, 5), (Ai, Aj, Ak) = (3, 3, 3)
2 : (i, j, k) = (1, 6, 9), (Ai, Aj, Ak) = (3, 4, 5)
3 : (i, j, k) = (1, 8, 9), (Ai, Aj, Ak) = (3, 4, 5)
4 : (i, j, k) = (3, 6, 9), (Ai, Aj, Ak) = (3, 4, 5)
5 : (i, j, k) = (3, 8, 9), (Ai, Aj, Ak) = (3, 4, 5)
6 : (i, j, k) = (4, 6, 10), (Ai, Aj, Ak) = (6, 4, 2)
7 : (i, j, k) = (4, 8, 10), (Ai, Aj, Ak) = (6, 4, 2)
8 : (i, j, k) = (5, 6, 9), (Ai, Aj, Ak) = (3, 4, 5)
9 : (i, j, k) = (5, 8, 9), (Ai, Aj, Ak) = (3, 4, 5)

题解:

    考虑分块,分成block块

    假设三个点都在同一块,那么我们就在一块内暴力,复杂度block * ( n/block)  * (n/block)

    假设其中两个点在同一块,那么枚举其中一块的两个点算答案,block * n/block * n/block

  ·  假设三个点都不在同一块,枚举中间点属于的那一块 剩下左边和右边进行 FFT, 复杂度block * (n*logn)

    

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define ls i<<1
#define rs ls | 1
#define mid ((ll+rr)>>1)
#define pii pair<int,int>
#define MP make_pair
typedef long long LL;
typedef unsigned long long ULL;
const long long INF = 1e18+1LL;
const double pi = acos(-1.0);
const int N = 3e5+, M = 1e6+, mod = 1e9+,inf = 2e9; struct Complex {
double r , i ;
Complex () {}
Complex ( double r , double i ) : r ( r ) , i ( i ) {}
Complex operator + ( const Complex& t ) const {
return Complex ( r + t.r , i + t.i ) ;
}
Complex operator - ( const Complex& t ) const {
return Complex ( r - t.r , i - t.i ) ;
}
Complex operator * ( const Complex& t ) const {
return Complex ( r * t.r - i * t.i , r * t.i + i * t.r ) ;
}
} ; void FFT ( Complex y[] , int n , int rev ) {
for ( int i = , j , t , k ; i < n ; ++ i ) {
for ( j = , t = i , k = n >> ; k ; k >>= , t >>= ) j = j << | t & ;
if ( i < j ) swap ( y[i] , y[j] ) ;
}
for ( int s = , ds = ; s <= n ; ds = s , s <<= ) {
Complex wn = Complex ( cos ( rev * * pi / s ) , sin ( rev * * pi / s ) ) , w ( , ) , t ;
for ( int k = ; k < ds ; ++ k , w = w * wn ) {
for ( int i = k ; i < n ; i += s ) {
y[i + ds] = y[i] - ( t = w * y[i + ds] ) ;
y[i] = y[i] + t ;
}
}
}
if ( rev == - ) for ( int i = ; i < n ; ++ i ) y[i].r /= n ;
}
Complex s[N],t[N]; LL cnt[][];
int a[N];
int n,block,pos[N];
LL vis[N];
int main() {
while(scanf("%d",&n)!=EOF) {
block = ;
for(int i = ; i <= n; ++i)
pos[i] = (i-)/block + ;
int mx = -;
for(int i = ; i <= pos[n]; ++i)
for(int j = ; j <= ; ++j) cnt[i][j] = ;
for(int i = ; i <= n; ++i) {
scanf("%d",&a[i]);
mx = max(mx,a[i]);
cnt[pos[i]][a[i]]++;
} for(int i = ; i <= mx; ++i) {
for(int j = ; j <= pos[n]; ++j) {
cnt[j][i] += cnt[j-][i];
}
}
int len = ;
while(len <= *mx) len<<=;
LL ans = ;
for(int k = ; k <= pos[n]; ++k) {
for(int i = (k-)*block + ; i <= min(k*block,n); ++i) {
for(int j = i + ; j <= min(k*block,n); ++j) {
if(*a[i] - a[j] >= && *a[i] - a[j] <= mx)
ans += cnt[k-][*a[i] - a[j]] + vis[*a[i]-a[j]];
if(*a[j] - a[i] >= && *a[j] - a[i] <= mx)
ans += cnt[pos[n]][*a[j] - a[i]] - cnt[k][*a[j] - a[i]];
}
vis[a[i]] += ;
}
for(int i = (k-)*block + ; i <= min(k*block,n); ++i) {
vis[a[i]] = ;
} for(int j = ; j <= mx; ++j)
s[j] = Complex(cnt[k-][j],);
for(int j = mx+; j < len; ++j) s[j] = Complex(,); for(int j = ; j <= mx; ++j)
t[j] = Complex(cnt[pos[n]][j] - cnt[k][j] , );
for(int j = mx+; j < len; ++j) t[j] = Complex(,); FFT(s,len,);FFT(t,len,);
for(int j = ; j < len; ++j) s[j] = s[j] * t[j];
FFT(s,len,-); for(int j = ; j <= mx; ++j) {
LL tmp = (LL)(s[*j].r + 0.5);
ans += tmp*(cnt[k][j] - cnt[k-][j]);
}
}
printf("%lld\n",ans); }
return ;
}

  

CodeChef - COUNTARI FTT+分块的更多相关文章

  1. [BZOJ 3509] [CodeChef] COUNTARI (FFT+分块)

    [BZOJ 3509] [CodeChef] COUNTARI (FFT+分块) 题面 给出一个长度为n的数组,问有多少三元组\((i,j,k)\)满足\(i<j<k,a_j-a_i=a_ ...

  2. BZOJ3509 [CodeChef] COUNTARI 【分块 + fft】

    题目链接 BZOJ3509 题解 化一下式子,就是 \[2A[j] = A[i] + A[k]\] 所以我们对一个位置两边的数构成的生成函数相乘即可 但是由于这样做是\(O(n^2logn)\)的,我 ...

  3. bzoj 3509: [CodeChef] COUNTARI] [分块 生成函数]

    3509: [CodeChef] COUNTARI 题意:统计满足\(i<j<k, 2*a[j] = a[i] + a[k]\)的个数 \(2*a[j]\)不太好处理,暴力fft不如直接暴 ...

  4. BZOJ 3509: [CodeChef] COUNTARI

    3509: [CodeChef] COUNTARI Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 883  Solved: 250[Submit][S ...

  5. BZOJ3509: [CodeChef] COUNTARI

    3509: [CodeChef] COUNTARI Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 339  Solved: 85[Submit][St ...

  6. CodeChef COUNTARI Arithmetic Progressions(分块 + FFT)

    题目 Source http://vjudge.net/problem/142058 Description Given N integers A1, A2, …. AN, Dexter wants ...

  7. BZOJ 3509 [CodeChef] COUNTARI ——分块 FFT

    分块大法好. 块内暴力,块外FFT. 弃疗了,抄SX队长$silvernebula$的代码 #include <map> #include <cmath> #include & ...

  8. CodeChef FNCS (分块+树状数组)

    题目:https://www.codechef.com/problems/FNCS 题解: 我们知道要求区间和的时候,我们用前缀和去优化.这里也是一样,我们要求第 l 个函数到第 r 个函数 [l, ...

  9. CodeChef - COUNTARI Arithmetic Progressions (FFT)

    题意:求一个序列中,有多少三元组$(i,j,k)i<j<k $ 满足\(A_i + A_k = 2*A_i\) 构成等差数列. https://www.cnblogs.com/xiuwen ...

随机推荐

  1. 【HTML/XML 1】HTML 速成总结

    导读:反反复复的看完了HTML的速成材料,前面学习了牛腩,所以这块知识只能是作为一种旧知识的复习.和机房重构时的SQLHelper一样,刚开始都是稀里糊涂的用了,后面系统的学习后,才知道为什么要那样用 ...

  2. Python MySQLdb的execute和executemany的使用

    如果使用executemany对数据进行批量插入的话,要注意一下事项: conn = MySQLdb.connect(host = “localhost”, user = “root”, passwd ...

  3. 【Luogu】P1119灾后重建(Floyd)

    题目链接 见题解: feilongz. 这里只放代码. #include<cstdio> #include<cstring> #include<cstdlib> # ...

  4. [UOJ#220][BZOJ4651][Noi2016]网格

    [UOJ#220][BZOJ4651][Noi2016]网格 试题描述 跳蚤国王和蛐蛐国王在玩一个游戏. 他们在一个 n 行 m 列的网格上排兵布阵.其中的 c 个格子中 (0≤c≤nm),每个格子有 ...

  5. spring之Annotation

    spring除了提供了@Autowired,还提供了以下几类annotation. 1.@Component, @Repository, @Service, @Controller @Reposito ...

  6. Log4j2异步情况下怎么防止丢日志的源码分析以及队列等待和拒绝策略分析

    org.apache.logging.log4j.core.async.AsyncLoggerConfigDisruptor以下所有源码均在此类中首先我们看下log4j2异步队列的初始化 从这里面我们 ...

  7. 洛谷试炼场 提高模板-nlogn数据结构

    树状数组-区间求和 P3374 [模板]树状数组 1 /*by SilverN*/ #include<algorithm> #include<iostream> #includ ...

  8. Laravel 控制器的session

    设置路由 //使用session,需要开启session,//session的开始类在/app/Kernel下//protected $middlewareGroups = [// 'web' =&g ...

  9. UI小结

    第一.UIButton的定义      UIButton *button=[[UIButton buttonWithType:(UIButtonType); 能够定义的button类型有以下6种,   ...

  10. codeforces 1051 F

    多源点最短路. 但是有限制,m - n <= 20,边数 - 点数 <= 20, 所以这个图非常的稀疏. 任意提取出一个生成树出来,LCA处理任意两点最短路. 然后再去遍历那些多余出来的点 ...