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 ...
随机推荐
- TCP内核参数
tcp_syn_retries :INTEGER默认值是5对于一个新建连接,内核要发送多少个 SYN 连接请求才决定放弃.不应该大于255,默认值是5,对应于180秒左右时间.(对于大负载而物理通信良 ...
- vue v-dialogDrag: 弹窗拖拽
Vue.directive('dialogDrag', { inserted:function(el) { const dragDom = el.querySelector('.jsPropupLay ...
- 算法复习——2—sat(bzoj2199)
题目: Description 由于对Farmer John的领导感到极其不悦,奶牛们退出了农场,组建了奶牛议会.议会以“每头牛 都可以获得自己想要的”为原则,建立了下面的投票系统: M只到场的奶牛 ...
- 刷题总结——子串(NOIP2015提高组)
题目: 题目背景 NOIP2015 提高组 Day2 T2 题目描述 有两个仅包含小写英文字母的字符串 A 和 B .现在要从字符串 A 中取出 k 个互不重叠的非空子串,然后把这 k 个子串按照其在 ...
- Java统计程序运行时间
代码如下: 第一种是以毫秒为单位计算的. long startTime = System.currentTimeMillis(); //获取开始时间 doSomething(); //测试 ...
- SHoj A序列
A序列 发布时间: 2017年7月9日 18:17 最后更新: 2017年7月9日 21:05 时间限制: 1000ms 内存限制: 128M 描述 如果一个序列有奇数个正整数组成,不妨令 ...
- [Hihocoder 1289] 403 Forbidden (微软2016校园招聘4月在线笔试)
传送门 #1289 : 403 Forbidden 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 Little Hi runs a web server. Someti ...
- HDU 5009 Paint Pearls(西安网络赛C题) dp+离散化+优化
转自:http://blog.csdn.net/accelerator_/article/details/39271751 吐血ac... 11668627 2014-09-16 22:15:24 A ...
- LeetCode OJ--Reverse Linked List II
http://oj.leetcode.com/problems/reverse-linked-list-ii/ 链表的操作 #include <iostream> using namesp ...
- HDU_4770 Lights Against Dudely 状压+剪枝
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4770 Lights Against Dudely Time Limit: 2000/1000 MS ( ...