3509: [CodeChef] COUNTARI

题意:统计满足\(i<j<k, 2*a[j] = a[i] + a[k]\)的个数


\(2*a[j]\)不太好处理,暴力fft不如直接暴力

考虑分块

每个块用生成函数统计j在块中ik在两边的块中的

有两个在块中或者三个都在暴力统计,实时维护两边权值出现次数

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <ctime>
using namespace std;
typedef long long ll;
const int N = (1<<16) + 5, M = 1e5+5;
const double PI = acos(-1.0);
inline int read() {
char c=getchar(); int x=0,f=1;
while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
return x*f;
} struct meow{
double x, y;
meow(double a=0, double b=0):x(a), y(b){}
};
meow operator +(meow a, meow b) {return meow(a.x+b.x, a.y+b.y);}
meow operator -(meow a, meow b) {return meow(a.x-b.x, a.y-b.y);}
meow operator *(meow a, meow b) {return meow(a.x*b.x-a.y*b.y, a.x*b.y+a.y*b.x);}
meow conj(meow a) {return meow(a.x, -a.y);}
typedef meow cd; namespace fft {
int n, rev[N];
cd omega[N], omegaInv[N];
void init(int lim) {
n = 1; while(n < lim) n <<= 1;
for(int i=0; i<n; i++) {
omega[i] = cd(cos(2*PI/n*i), sin(2*PI/n*i));
omegaInv[i] = conj(omega[i]);
}
}
void dft(cd *a, int n, int flag) {
cd *w = flag == 1 ? omega : omegaInv;
int k = 0; while((1<<k) < n) k++;
for(int i=0; i<n; i++) {
rev[i] = (rev[i>>1]>>1) | ((i&1)<<(k-1));
if(i < rev[i]) swap(a[i], a[rev[i]]);
}
for(int l=2; l<=n; l<<=1) {
int m = l>>1;
for(cd *p = a; p != a+n; p += l)
for(int k=0; k<m; k++) {
cd t = w[n/l*k] * p[k+m];
p[k+m] = p[k] - t;
p[k] = p[k] + t;
}
}
if(flag == -1) for(int i=0; i<n; i++) a[i].x /= n;
}
void mul(cd *a, cd *b) {
dft(a, n, 1); dft(b, n, 1);
for(int i=0; i<n; i++) a[i] = a[i] * b[i];
dft(a, n, -1);
}
} int n, a[M], c1[N], c2[N], block, m;
cd p[N], q[N];
ll ans;
int main() {
freopen("in", "r", stdin);
n=read();
block = min(n, 8 * (int) sqrt(n));
for(int i=1; i<=n; i++) a[i] = read(), c2[a[i]]++, m = max(m, a[i]);
fft::init(m+m+1);
for(int l=1; l<=n; l+=block) {
int r = min(n, l+block-1);
for(int i=l; i<=r; i++) c2[a[i]]--;
for(int i=l; i<=r; i++) {
for(int j=i+1; j<=r; j++) {
int t = (a[j]<<1) - a[i];
if(t >= 0) ans += c2[t];
t = (a[i]<<1) - a[j];
if(t >= 0) ans += c1[t];
}
c1[a[i]]++;
}
//printf("hi [%d, %d] %lld\n", l, r, ans);
}
for(int l=1; l<=n; l+=block) { //printf("l %d\n", l);
int r = min(n, l+block-1);
memset(p, 0, sizeof(p)); memset(q, 0, sizeof(q));
for(int i=1; i<l; i++) p[a[i]].x ++;
for(int i=r+1; i<=n; i++) q[a[i]].x ++;
fft::mul(p, q);
for(int i=l; i<=r; i++) ans += (ll) floor(p[a[i]<<1].x + 0.5);
}
printf("%lld", ans);
//printf("\n%lf", (double) clock() / CLOCKS_PER_SEC);
}

bzoj 3509: [CodeChef] COUNTARI] [分块 生成函数]的更多相关文章

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

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

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

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

  3. BZOJ 3509: [CodeChef] COUNTARI

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

  4. BZOJ3509: [CodeChef] COUNTARI

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

  5. CC countari & 分块+FFT

    题意: 求一个序列中顺序的长度为3的等差数列. SOL: 对于这种计数问题都是用个数的卷积来进行统计.然而对于这个题有顺序的限制,不好直接统计,于是竟然可以分块?惊为天人... 考虑分块以后的序列: ...

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

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

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

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

  8. CodeChef - COUNTARI FTT+分块

    Arithmetic Progressions Given N integers A1, A2, …. AN, Dexter wants to know how many ways he can ch ...

  9. BZOJ 3509 分块FFT

    思路: 跟今年WC的题几乎一样 (但是这道题有重 不能用bitset水过去) 正解:分块FFT http://blog.csdn.net/geotcbrl/article/details/506364 ...

随机推荐

  1. 在64位系统下,指向int型的指针占的内存空间多大?

    不废话,请看代码演示如下: 注意使用的操作系统的位数,不同位数的操作系统,结果不一样! 我是用的是64位的操作系统! linux下示例代码如下: #include <stdio.h> in ...

  2. C语言中%d,%p,%u,%lu等都有什么用处

    %d 有符号10进制整数(%ld 长整型,%hd短整型 )%hu 无符号短整形(%u无符号整形,%lu无符号长整形)%i 有符号10进制整数 (%i 和%d 没有区别,%i 是老式写法,都是整型格式) ...

  3. cin与cout详解

    输入和输出并不是C++语言中的正式组成成分。C和C++本身都没有为输入和输出提供专门的语句结构。输入输出不是由C++本身定义的,而是在编译系统提供的I/O库中定义的。C++的输出和输入是用" ...

  4. Docker版本升级至17.03

    2017/3/3,Docker官方发表了一篇博客,Docker版本从1.13.*直接跳入17.03,该版本的意思是17年3月.同时,还声明了Docker以后会以CE(Community Edition ...

  5. cesium编程入门(三)开始使用cesium开发

    搭建最简的开发环境 这一节来搭建一个最简单的能运行的helloworld,以后的代码也会在这一节的基础上慢慢增加 创建文件夹 mkdir cesium-test cd cesium-test 引入编译 ...

  6. 我的第一个python web开发框架(20)——产品发布(部署到服务器)

    首先按上一章节所讲述的,将服务器环境安装好以后,接下来就是按步骤将网站部署到服务器上了. 我们的站点是前后端分离的,所以需要部署两个站点.首先来发布前端站点. 部署前端站点 输入命令进入svn管理文件 ...

  7. vue引入新版 vue-awesome-swiper填坑

    关于新版 vue-awesome-swiper 问题 为什么我的vue-awesome-swiper组件pagination小圆点不显示问题? 为什么我的vue-awesome-swiper不会自动播 ...

  8. DTD约束

    DTD约束 一,导入DTD方式   二,DTD语法 2)DTD语法 约束标签 <!ELEMENT 元素名称类别>或<!ELEMENT 元素名称(元素内容)> 类别: 空标签: ...

  9. 请问:关于织梦dedecms点击导航上的父栏目进去默认显示第一个子栏目的列表的问题

    要设置织梦dedecms点击导航上的父栏目进去默认显示第一个子栏目的列表, 就按照如下图所示的方法进行操作,为什么 点击导航上的父栏目出现死循环呢, 根本浏览不了网页. 请各位大神指点指点,为什么点击 ...

  10. c#动态编译并执行字符串

    比较简单,步骤是这样的 string -> compiler -> assembly -> reflection -> execution 直接上代码: using Syste ...