题目链接

BZOJ3509

题解

化一下式子,就是

\[2A[j] = A[i] + A[k]
\]

所以我们对一个位置两边的数构成的生成函数相乘即可

但是由于这样做是\(O(n^2logn)\)的,我们考虑如何优化

显然可以分块做,我们不对所有数左右求卷积,只对\(B\)个块左右做,这样\(i\)和\(k\)都在块外的情况就可以统计出来

\(i\)或\(k\)在块内的情况可以暴力扫一遍计算

复杂度\(O(Bnlogn + nB)\)

经计算\(B = \sqrt{nlogn}\)最优

但考虑到\(fft\)的常数问题,\(B = 2000\)左右比较合理

复杂度就大概是\(O((nlogn)^{\frac{3}{2}})\)

竟然能\(A\)....

交上去就垫底了。。

  1. #include<algorithm>
  2. #include<iostream>
  3. #include<cstring>
  4. #include<cstdio>
  5. #include<cmath>
  6. #define REP(i,n) for (register int i = 1; i <= (n); i++)
  7. #define mp(a,b) make_pair<int,int>(a,b)
  8. #define cp pair<int,int>
  9. #define LL long long int
  10. #define res register
  11. using namespace std;
  12. const int maxn = 400005,maxm = 4005,INF = 1000000000;
  13. inline int read(){
  14. int out = 0,flag = 1; char c = getchar();
  15. while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
  16. while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
  17. return out * flag;
  18. }
  19. struct E{
  20. double a,b;
  21. E(){}
  22. E(double x,double y):a(x),b(y) {}
  23. E(int x,int y):a(x),b(y) {}
  24. inline E operator =(const int& b){
  25. this->a = b; this->b = 0;
  26. return *this;
  27. }
  28. inline E operator =(const double& b){
  29. this->a = b; this->b = 0;
  30. return *this;
  31. }
  32. inline E operator /=(const double& b){
  33. this->a /= b; this->b /= b;
  34. return *this;
  35. }
  36. };
  37. inline E operator *(const E& a,const E& b){
  38. return E(a.a * b.a - a.b * b.b,a.a * b.b + a.b * b.a);
  39. }
  40. inline E operator *=(E& a,const E& b){
  41. return a = E(a.a * b.a - a.b * b.b,a.a * b.b + a.b * b.a);
  42. }
  43. inline E operator +(const E& a,const E& b){
  44. return E(a.a + b.a,a.b + b.b);
  45. }
  46. inline E operator -(const E& a,const E& b){
  47. return E(a.a - b.a,a.b - b.b);
  48. }
  49. const double pi = acos(-1);
  50. int R[maxn];
  51. void fft(E* a,int n,int f){
  52. for (res int i = 0; i < n; i++) if (i < R[i]) swap(a[i],a[R[i]]);
  53. for (res int i = 1; i < n; i <<= 1){
  54. E wn(cos(pi / i),f * sin(pi / i));
  55. for (res int j = 0; j < n; j += (i << 1)){
  56. E w(1,0),x,y;
  57. for (res int k = 0; k < i; k++,w = w * wn){
  58. x = a[j + k],y = w * a[j + k + i];
  59. a[j + k] = x + y; a[j + k + i] = x - y;
  60. }
  61. }
  62. }
  63. if (f == -1) for (int i = 0; i < n; i++) a[i] /= n;
  64. }
  65. E A[maxn],C[maxn];
  66. int N,B,val[maxn],b[maxn],bl[maxm],br[maxm],bi;
  67. LL ans;
  68. void work1(){
  69. for (res int x = 2; x < bi; x++){
  70. int deg1 = 0,deg2 = 0;
  71. for (res int i = 1; b[i] != x; i++)
  72. A[val[i]].a++,deg1 = max(deg1,val[i]);
  73. for (res int i = N; b[i] != x; i--)
  74. C[val[i]].a++,deg2 = max(deg2,val[i]);
  75. int n = 1,L = 0;
  76. while (n <= deg1 + deg2) n <<= 1,L++;
  77. for (res int i = 1; i < n; i++) R[i] = (R[i >> 1] >> 1) | ((i & 1) << (L - 1));
  78. fft(A,n,1); fft(C,n,1);
  79. for (res int i = 0; i < n; i++) A[i] *= C[i];
  80. fft(A,n,-1);
  81. for (res int i = bl[x]; i <= br[x]; i++)
  82. ans += (LL)floor(A[val[i] << 1].a + 0.1);
  83. for (res int i = 0; i < n; i++) A[i] = C[i] = 0.0;
  84. }
  85. }
  86. int bac[maxn],M;
  87. void work2(){
  88. for (res int i = 1; i <= N; i++){
  89. for (res int j = i + 1; b[j] == b[i]; j++){
  90. if (val[j] >= val[i] && val[i] >= val[j] - val[i])
  91. ans += bac[val[i] - (val[j] - val[i])];
  92. if (val[j] < val[i] && val[i] + val[i] - val[j] <= 30000)
  93. ans += bac[val[i] + val[i] - val[j]];
  94. }
  95. bac[val[i]]++;
  96. }
  97. REP(i,N) bac[val[i]]--;
  98. for (res int i = N; i; i--){
  99. for (res int j = i - 1; b[j] == b[i]; j--){
  100. if (val[j] >= val[i] && val[i] >= val[j] - val[i])
  101. ans += bac[val[i] - (val[j] - val[i])];
  102. if (val[j] < val[i] && val[i] + val[i] - val[j] <= 30000)
  103. ans += bac[val[i] + val[i] - val[j]];
  104. }
  105. bac[val[i]]++;
  106. }
  107. REP(i,N) bac[val[i]]--;
  108. for (res int x = 1; x <= bi; x++){
  109. for (res int i = bl[x]; i <= br[x]; i++){
  110. for (res int j = i + 1; j <= br[x]; j++){
  111. if (val[j] >= val[i] && val[i] >= val[j] - val[i])
  112. ans -= bac[val[i] - (val[j] - val[i])];
  113. if (val[j] < val[i] && val[i] + val[i] - val[j] <= 30000)
  114. ans -= bac[val[i] + val[i] - val[j]];
  115. }
  116. bac[val[i]]++;
  117. }
  118. for (int i = bl[x]; i <= br[x]; i++) bac[val[i]]--;
  119. }
  120. }
  121. int main(){
  122. N = read(); B = 2000;
  123. REP(i,N){
  124. val[i] = read(),b[i] = i / B + 1,M = max(M,val[i]);
  125. if (b[i] != b[i - 1]) br[b[i - 1]] = i - 1,bl[b[i]] = i;
  126. }
  127. br[b[N]] = N; bi = b[N];
  128. work1();
  129. work2();
  130. printf("%lld\n",ans);
  131. return 0;
  132. }

BZOJ3509 [CodeChef] COUNTARI 【分块 + fft】的更多相关文章

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

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

  2. CC countari & 分块+FFT

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

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

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

  4. BZOJ3509: [CodeChef] COUNTARI

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

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

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

  6. BZOJ 3509: [CodeChef] COUNTARI

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

  7. BZOJ 3509 分块FFT

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

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

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

  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. [Bootstrap 源码解析]——bootstrap源码之初始化

    bootstrap源码之初始化 我们先来分析normalize.less编译后的源码,我们知道normalize.css是一个专门将不同浏览器的默认css特性设置为统一效果的css库,它和reset. ...

  2. Spring学习(九)-----Spring bean配置继承

    在 Spring,继承是用为支持bean设置一个 bean 来分享共同的值,属性或配置. 一个子 bean 或继承的bean可以继承其父 bean 的配置,属性和一些属性.另外,子 Bean 允许覆盖 ...

  3. commons fileupload上传报错

    这个问题困扰我好久了一直没有找到解决方法,先记录下来. 生产环境(简称A)上老是出错,而测试环境(简称B)一切正常. 我们的框架是JAVA语言编写,基于struts1技术总监自己搭的框架,我在stru ...

  4. 杂谈微服务架构下SSO&OpenAPI访问的方案。

    本篇杂谈下微服务架构下WEB应用的浏览器与OpenAPI访问架构与方案.读者可对比传统架构下应用的此话话题的区别.或者有其它方案的欢迎交流

  5. 01_基于TCP的循环为同一个客户端下载文件的下载器

    原版: TCP分为客户端(client)和服务器(server),每次服务器只能为客户端提供一次的下载服务. 改良版: TCP分为客户端(client)和服务器(server), (1)每次服务器能为 ...

  6. Python基础知识-06-集合内存布尔False

    python其他知识目录 1.判断一个字符串中是否有敏感字符? #str: m_str="我叫魔降风云变" if "魔" in m_str: #判断指定字符是否 ...

  7. 扩展Lucas定理 扩展Lucas板子

    题意概述:多组询问,给出N,K,M,要求回答C(N,K)%M,1<=N<=10^18,1<=K<=N,2<=M<=10^6 分析: 模数不为质数只能用扩展Lucas ...

  8. socket编程 123

    1. 预备知识 一直以来很少看到有多少人使用php的socket模块来做一些事情,大概大家都把它定位在脚本语言的范畴内吧,但是其实php的socket模块可以做很多事情,包括做ftplist,http ...

  9. winfrom 界面编辑之疑难杂症

    设计器方便,但是也存在一些问题: 1.找不到控件,但确实存在——被隐藏或被右键显示于底层或颜色与父容器一致. 解决办法: 修改隐藏属性或右键显示于顶层. 2.灵活运用右键锁定控件与解锁控件. 3.注意 ...

  10. Java 数组转字符

    public static String toString(int[] arr){ String temp = ""; for(int i = 0;i<arr.length; ...