CodeChef - COUNTARI FTT+分块
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+分块的更多相关文章
- [BZOJ 3509] [CodeChef] COUNTARI (FFT+分块)
[BZOJ 3509] [CodeChef] COUNTARI (FFT+分块) 题面 给出一个长度为n的数组,问有多少三元组\((i,j,k)\)满足\(i<j<k,a_j-a_i=a_ ...
- BZOJ3509 [CodeChef] COUNTARI 【分块 + fft】
题目链接 BZOJ3509 题解 化一下式子,就是 \[2A[j] = A[i] + A[k]\] 所以我们对一个位置两边的数构成的生成函数相乘即可 但是由于这样做是\(O(n^2logn)\)的,我 ...
- bzoj 3509: [CodeChef] COUNTARI] [分块 生成函数]
3509: [CodeChef] COUNTARI 题意:统计满足\(i<j<k, 2*a[j] = a[i] + a[k]\)的个数 \(2*a[j]\)不太好处理,暴力fft不如直接暴 ...
- BZOJ 3509: [CodeChef] COUNTARI
3509: [CodeChef] COUNTARI Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 883 Solved: 250[Submit][S ...
- BZOJ3509: [CodeChef] COUNTARI
3509: [CodeChef] COUNTARI Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 339 Solved: 85[Submit][St ...
- CodeChef COUNTARI Arithmetic Progressions(分块 + FFT)
题目 Source http://vjudge.net/problem/142058 Description Given N integers A1, A2, …. AN, Dexter wants ...
- BZOJ 3509 [CodeChef] COUNTARI ——分块 FFT
分块大法好. 块内暴力,块外FFT. 弃疗了,抄SX队长$silvernebula$的代码 #include <map> #include <cmath> #include & ...
- CodeChef FNCS (分块+树状数组)
题目:https://www.codechef.com/problems/FNCS 题解: 我们知道要求区间和的时候,我们用前缀和去优化.这里也是一样,我们要求第 l 个函数到第 r 个函数 [l, ...
- CodeChef - COUNTARI Arithmetic Progressions (FFT)
题意:求一个序列中,有多少三元组$(i,j,k)i<j<k $ 满足\(A_i + A_k = 2*A_i\) 构成等差数列. https://www.cnblogs.com/xiuwen ...
随机推荐
- 命令行-s的意思
-s,signal,意思就是信号,一般是发送信号. 如: # 关闭 nginx -s stop;
- 网页QQ唤起
网页QQ唤起 <html> <head> <meta http-equiv="Content-Type" content="text/htm ...
- 【Kubernetes】Deployment控制器模型
在Kubernetes中,Deployment是最基本的控制器对象 apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deploym ...
- BZOJ 1191: [HNOI2006]超级英雄Hero【二分图匹配】
裸的匹配题,一眼就能看出来二分图的模型,是某个经典题的改编.貌似某本图论书上讲过的,有N个人以及M个职位,每个职位只能提供给一个人,而每个人由于能力有限只能胜任有限个职位,问是否有办法使得每个人都有工 ...
- 洛谷 [P2734] 游戏
博弈论+区间dp 有博弈论吗?大约只有一个博弈论的壳子 设 dp[i][j] 表示区间 i ~ j 先手最多能取多少, 它可以由 i ~ j - 1 与 i + 1 ~ j 来转移, 等于上述两个区间 ...
- CSS参数介绍
原文发布时间为:2008-08-03 -- 来源于本人的百度文章 [由搬家工具导入] 行高 line-height: 16px 宽度 (具体位置)-width: 16px 文字 ...
- webstorm取消自动保存并标识修改的文件为星星标记
a.取消自动保存是去掉一下两个勾选. b.标记星星要勾选下面的选项. c.最终效果.
- Codeforces 665C Simple Strings【暴力,贪心】
题目链接: http://codeforces.com/contest/665/problem/C 题意: 改变最少的字符,使得最终序列无相同的连续的字符. 分析: 对每一个与前一个字符相同的字符,枚 ...
- DFS与BFS对比
前面已经说过了深搜和广搜了,是不是有点还不是很好的分清他们?(其实分不分的请都没大有关系) 下面我们来看一看广搜与深搜的区别吧. 算法步骤上的区别 深度优先遍历图算法步骤: 1.访问顶点v 2,.依次 ...
- Java 一个?格式的解决
用Java 出现了这样的一个问题?好几天都没解决掉 然后最近一直找资料 截个图: 本来格式中时没有这个?号的,代码里面用GBK和utf-8都不能解决. 即使我加了 Str.trim(Str)去除 字符 ...