BZOJ-3509 母函数+分块+暴力+FFT
题目描述
给定一个长度为N的数组A[],求有多少对i, j, k(1<=i<j<k<=N)满足A[k]-A[j]=A[j]-A[i]。
输入格式
第一行一个整数N(N<=10^5)。
接下来一行N个数A[i](A[i]<=30000)。
输出格式
一行一个整数。
样例输入
10
3 5 3 6 3 4 10 4 5 2
样例输出
9 这题网上题解很多
我的第一个想法是枚举 j 然后左边的数 和 右边的数 FFT处理一下
这样的复杂度是 n^2*log(n) 复杂度明显不行 所以需要进一步的优化
网上题解都是用分块进行优化
先在每一个块里面找一下是否存在满足条件的
然后再找块外面的满足条件的
这题BZOJ 开了40S 跑的了的
我FFT是直接套板子 当作黑盒使用 所有代码有点鬼畜
#include <cstdio>
#include <cstring>
#include <queue>
#include <cmath>
#include <algorithm>
#include <set>
#include <iostream>
#include <map>
#include <stack>
#include <string>
#include <vector>
#define pi acos(-1.0)
#define eps 1e-9
#define fi first
#define se second
#define rtl rt<<1
#define rtr rt<<1|1
#define bug printf("******\n")
#define mem(a,b) memset(a,b,sizeof(a))
#define name2str(x) #x
#define fuck(x) cout<<#x" = "<<x<<endl
#define f(a) a*a
#define sf(n) scanf("%d", &n)
#define sff(a,b) scanf("%d %d", &a, &b)
#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
#define sffff(a,b,c,d) scanf("%d %d %d %d", &a, &b, &c, &d)
#define pf printf
#define FRE(i,a,b) for(i = a; i <= b; i++)
#define FREE(i,a,b) for(i = a; i >= b; i--)
#define FRL(i,a,b) for(i = a; i < b; i++)+
#define FRLL(i,a,b) for(i = a; i > b; i--)
#define FIN freopen("data.txt","r",stdin)
#define gcd(a,b) __gcd(a,b)
#define lowbit(x) x&-x
#define rep(i,a,b) for(int i=a;i<b;++i)
#define per(i,a,b) for(int i=a-1;i>=b;--i)
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int maxn = 3e5 + ;
const int maxm = maxn * ;
int n, m, a[maxn], b[maxn];
int len, res[maxm], mx; //开大4倍
struct cpx {
long double r, i;
cpx ( long double r = , long double i = ) : r ( r ), i ( i ) {};
cpx operator+ ( const cpx &b ) {
return cpx ( r + b.r, i + b.i );
}
cpx operator- ( const cpx &b ) {
return cpx ( r - b.r, i - b.i );
}
cpx operator* ( const cpx &b ) {
return cpx ( r * b.r - i * b.i, i * b.r + r * b.i );
}
} va[maxm], vb[maxm];
void rader ( cpx F[], int len ) { //len = 2^M,reverse F[i] with F[j] j为i二进制反转
int j = len >> ;
for ( int i = ; i < len - ; ++i ) {
if ( i < j ) swap ( F[i], F[j] ); // reverse
int k = len >> ;
while ( j >= k ) j -= k, k >>= ;
if ( j < k ) j += k;
}
}
void FFT ( cpx F[], int len, int t ) {
rader ( F, len );
for ( int h = ; h <= len; h <<= ) {
cpx wn ( cos ( -t * * pi / h ), sin ( -t * * pi / h ) );
for ( int j = ; j < len; j += h ) {
cpx E ( , ); //旋转因子
for ( int k = j; k < j + h / ; ++k ) {
cpx u = F[k];
cpx v = E * F[k + h / ];
F[k] = u + v;
F[k + h / ] = u - v;
E = E * wn;
}
}
}
if ( t == - ) //IDFT
for ( int i = ; i < len; ++i ) F[i].r /= len;
}
void Conv ( cpx a[], cpx b[], int len ) { //求卷积
FFT ( a, len, );
FFT ( b, len, );
for ( int i = ; i < len; ++i ) a[i] = a[i] * b[i];
FFT ( a, len, - );
}
void gao () {
len = ;
mx = n + m;
while ( len <= mx ) len <<= ; //mx为卷积后最大下标
for ( int i = ; i < len; i++ ) va[i].r = va[i].i = vb[i].r = vb[i].i = ;
for ( int i = ; i < n; i++ ) va[i].r = a[i]; //根据题目要求改写
for ( int i = ; i < m; i++ ) vb[i].r = b[i]; //根据题目要求改写
Conv ( va, vb, len );
for ( int i = ; i < len; ++i ) res[i] += ( LL ) floor ( va[i].r + 0.5 );
}
int L[maxn], R[maxn], p[maxn];
int main() {
//FIN;
int num;
sf ( num );
m = -;
for ( int i = ; i < num ; i++ ) {
sf ( p[i] );
R[p[i]]++;
m = max ( m, p[i] );
}
m++;
n = m;
int sz = min ( num, * ( int ) sqrt ( num ) );
LL ans = ;
for ( int i = ; i < num ; i += sz ) {
int r = min ( num, i + sz ) - ;
for ( int j = i ; j <= r ; j++ ) R[p[j]]--;
for ( int j = i, x ; j <= r ; j++ ) {
for ( int k = j + ; k <= r ; k++ ) {
x = * p[j] - p[k];
if ( x >= ) ans += 1LL * L[x];
x = * p[k] - p[j];
if ( x >= ) ans += 1LL * R[x];
}
L[p[j]]++;
}
}
for ( int i = ; i < num ; i += sz ) {
int r = min ( num, i + sz ) - ;
mem ( a, ), mem ( b, ), mem ( res, );
for ( int j = ; j < i ; j++ ) a[p[j]]++;
for ( int j = r + ; j < num ; j++ ) b[p[j]]++;
gao();
for ( int j = i ; j <= r ; j++ ) ans += 1LL * ( res[ * p[j]] );
}
printf ( "%lld\n", ans );
return ;
}
BZOJ-3509 母函数+分块+暴力+FFT的更多相关文章
- [BZOJ 3509] [CodeChef] COUNTARI (FFT+分块)
[BZOJ 3509] [CodeChef] COUNTARI (FFT+分块) 题面 给出一个长度为n的数组,问有多少三元组\((i,j,k)\)满足\(i<j<k,a_j-a_i=a_ ...
- bzoj 3509: [CodeChef] COUNTARI] [分块 生成函数]
3509: [CodeChef] COUNTARI 题意:统计满足\(i<j<k, 2*a[j] = a[i] + a[k]\)的个数 \(2*a[j]\)不太好处理,暴力fft不如直接暴 ...
- Codeforces Beta Round #13 E. Holes 分块暴力
E. Holes Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/13/problem/E Des ...
- Codeforces#86D Powerful array(分块暴力)
Description An array of positive integers a1, a2, ..., an is given. Let us consider its arbitrary su ...
- [BZOJ 3456]城市规划(cdq分治+FFT)
[BZOJ 3456]城市规划(cdq分治+FFT) 题面 求有标号n个点无向连通图数目. 分析 设\(f(i)\)表示\(i\)个点组成的无向连通图数量,\(g(i)\)表示\(i\)个点的图的数量 ...
- Codeforces 1290D - Coffee Varieties(分块暴力+完全图的链覆盖)
Easy version:Codeforces 题面传送门 & 洛谷题面传送门 Hard version:Codeforces 题面传送门 & 洛谷题面传送门 发现自己交互题烂得跟 s ...
- BZOJ 3509 [CodeChef] COUNTARI ——分块 FFT
分块大法好. 块内暴力,块外FFT. 弃疗了,抄SX队长$silvernebula$的代码 #include <map> #include <cmath> #include & ...
- BZOJ 3509 分块FFT
思路: 跟今年WC的题几乎一样 (但是这道题有重 不能用bitset水过去) 正解:分块FFT http://blog.csdn.net/geotcbrl/article/details/506364 ...
- Bzoj 2038: [2009国家集训队]小Z的袜子(hose) 莫队,分块,暴力
2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec Memory Limit: 259 MBSubmit: 5763 Solved: 2660[Subm ...
随机推荐
- python其他知识目录
博客目录总纲首页 基础的重要性(程序员之路) 做一个“合格”的程序员(一)——基础能力 作为一个程序员,数学对你到底有多重要 同样是程序员,为什么别人比你更优秀? ------------------ ...
- mail邮件详解
基础命令学习目录首页 1.配置 vim /etc/mail.rc文件尾增加以下内容 set from=1968089885@qq.com smtp="smtp.qq.com"s ...
- Java试验四
北京电子科技学院(BESTI) 实 验 报 告 课程: Java 班级:1352 姓名:朱国庆 学号:20135237 成绩: ...
- 【搜索】POJ-3009 DFS+回溯
一.题目 Description On Planet MM-21, after their Olympic games this year, curling is getting popular. B ...
- Think In Java读书笔记:内部类覆盖及其初始化
本文相关章节:第十章 内部类 10.10 内部类可以被覆盖吗 在读至本节第二个范例代码时(及下方的代码),我对输出结果中的第一个“Egg.Yolk()”很不理解,为什么它会第一个地方输出. 我起初认为 ...
- yaf windows安装
1.需要先下载 php_yaf模块.地址(http://pecl.php.net/package/yaf/2.3.2/windows) 看清你的php版本,然后在phpinfo中看Achitectur ...
- 初入码田--ASP.NET MVC4 Web应用之创建一个空白的MVC应用程序
初入码田--ASP.NET MVC4 Web应用开发之一 实现简单的登录 初入码田--ASP.NET MVC4 Web应用开发之二 实现简单的增删改查 2016-07-29 在此之前,需要一台电脑( ...
- mysql 添加行号
首先准备演示数 DROP TABLE IF EXISTS `computer_stu`; CREATE TABLE `computer_stu` ( `id` ) NOT NULL, `name` ) ...
- Acdream1311_Apple
无聊的时候看到上一次acdream群赛的一个题目,中间居然是有alice和bob的博弈题目,于是就去做了. 给n,m,两人轮流操作,每次操作可以使n+1,或者m+1,谁操作后满足nm>=A,那么 ...
- 转载manifold learning一篇
我恨自己不干活儿,不过也没辙. 早晚要学习流形的,今天先转一篇文章,以后找不到就尿了. 我真羡慕数学系的人,╮(╯▽╰)╭. 发信人: Kordan (K&M), 信区: AI标 题: do ...