题意:给定一个序列,求多少个三元组满足ai+ak=2*aj(i<j<k)。

题解:原来叉姐的讲义上有啊。。完全忘掉了。。

首先这个式子很明显是一个卷积。我们有了FFT的思路。但是肯定不能每一个数都去做一次。那怎么办呢?我们分块吧!(分块大法好)

对于每一个块我们统计出前面块的桶,同理我们也有后面块的桶,两个桶FFT一下我们就得到了以这个块内元素为j,i和k分别在前面的块与后面的块的方案了。然后我们还要解决两个在一个块,三个在一个块的问题。两个在一个块的我们直接去前后的桶里找,同一个块的直接n*n暴力。然后就做完啦!好妙啊!

这题被坑了好久。。因为空间莫名其妙的问题怎么都算不对(块开极端都可以,就是开中间不行),然后一个下午没有了。。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define LL long long
  4. #define N 205005
  5. #define INF 1e9
  6. #define Bl 70
  7. #define LIM 60000
  8. const double PI=acos(-);
  9.  
  10. inline LL read(){
  11. LL x=,f=; char a=getchar();
  12. while(a<'' || a>'') {if(a=='-') f=-; a=getchar();}
  13. while(a>='' && a<='') x=x*+a-'',a=getchar();
  14. return x*f;
  15. }
  16.  
  17. namespace FFT{
  18. int rev[N];
  19.  
  20. struct vec{
  21. double r,i;
  22. vec operator * (const vec& w){return (vec){r*w.r-i*w.i,i*w.r+r*w.i};}
  23. vec operator + (const vec& w){return (vec){r+w.r,i+w.i};}
  24. vec operator - (const vec& w){return (vec){r-w.r,i-w.i};}
  25. }A[N],B[N];
  26.  
  27. inline void fft(vec* x,int len,int f){
  28. for(int i=;i<=len;i++) if(i<rev[i]) swap(x[i],x[rev[i]]);
  29. for(int lnow=;lnow<=len;lnow<<=){
  30. vec w,w0=(vec){cos(2.0*PI/lnow*f),sin(2.0*PI/lnow*f)},t1,t2;
  31. for(int i=;i<len;i+=lnow){
  32. w=(vec){,};
  33. for(int j=i;j<i+lnow/;j++){
  34. t1=x[j]; t2=w*x[j+lnow/];
  35. x[j]=t1+t2; x[j+lnow/]=t1-t2;
  36. w=w*w0;
  37. }
  38. }
  39. }
  40. }
  41.  
  42. inline void work(int a[],int b[],int l1,int l2,LL s[]){
  43. int len,t;
  44. for(len=,t=;len<=(l1+l2+);len<<=,t++); t=<<(t-);
  45. for(int i=;i<=len;i++) rev[i]=rev[i>>]>>|(i&?t:);
  46. for(int i=;i<=len;i++) B[i]=A[i]=(vec){,};
  47. for(int i=;i<=l1;i++) A[i].r=a[i];
  48. for(int i=;i<=l2;i++) B[i].r=b[i];
  49. fft(A,len,); fft(B,len,);
  50. for(int i=;i<=len;i++) A[i]=A[i]*B[i];
  51. fft(A,len,-);
  52. for(int i=;i<=l1+l2;i++)
  53. s[i]=(LL)(1.0*A[i].r/len+0.5);
  54. }
  55.  
  56. }
  57.  
  58. int n,block_size,block_num;
  59. int bel[N],l[Bl+],r[Bl+],a[N];
  60. LL tot,ans[*LIM+];
  61. int lsum[LIM+],rsum[LIM+],cnt[*LIM+];
  62.  
  63. inline void brutal_force(int x){
  64. for(int i=l[x];i<=r[x];i++) rsum[a[i]]--;
  65. memset(ans,,sizeof(ans));
  66. FFT::work(lsum,rsum,,,ans);
  67. for(int i=l[x];i<=r[x];i++){
  68. tot+=ans[*a[i]];
  69. for(int j=l[x];j<i;j++)
  70. if(*a[i]-a[j]>) tot+=rsum[*a[i]-a[j]];
  71. for(int j=i+;j<=r[x];j++)
  72. if(*a[i]-a[j]>) tot+=lsum[*a[i]-a[j]];
  73. }
  74. for(int i=l[x];i<=r[x];i++) lsum[a[i]]++;
  75. memset(cnt,,sizeof(cnt));
  76. for(int i=l[x];i<=r[x];i++){
  77. tot+=cnt[a[i]];
  78. for(int j=l[x];j<i;j++)
  79. if(*a[i]-a[j]>) cnt[*a[i]-a[j]]++;
  80. }
  81. }
  82.  
  83. int main(){
  84. n=read(); block_size=;
  85. block_num=(n-)/block_size+;
  86. for(int i=;i<=n;i++) a[i]=read(),bel[i]=(i-)/block_size+;
  87. for(int i=;i<=block_num;i++) l[i]=(i-)*block_size+,r[i]=min(n,i*block_size);
  88. for(int i=;i<=n;i++) rsum[a[i]]++;
  89. for(int i=;i<=block_num;i++) brutal_force(i);
  90. printf("%lld\n",tot);
  91. return ;
  92. }

[Codechef November Challenge 2012] Arithmetic Progressions的更多相关文章

  1. 【分块+树状数组】codechef November Challenge 2014 .Chef and Churu

    https://www.codechef.com/problems/FNCS [题意] [思路] 把n个函数分成√n块,预处理出每块中各个点(n个)被块中函数(√n个)覆盖的次数 查询时求前缀和,对于 ...

  2. CodeChef November Challenge 2013 部分题解

    http://www.codechef.com/NOV13 还在比...我先放一部分题解吧... Uncle Johny 排序一遍 struct node{ int val; int pos; }a[ ...

  3. Codechef November Challenge 2019 Division 1

    Preface 这场CC好难的说,后面的都不会做QAQ 还因为不会三进制位运算卷积被曲明姐姐欺负了,我真是太菜了QAQ PS:最后还是狗上了六星的说,期待两(三)场之内可以上七星 Physical E ...

  4. CodeChef November Challenge 2014

    重点回忆下我觉得比较有意义的题目吧.水题就只贴代码了. Distinct Characters Subsequence 水. 代码: #include <cstdio> #include ...

  5. CodeChef November Challenge 2019 Division 1题解

    传送门 AFO前的最后一场CC了--好好打吧-- \(SIMGAM\) 偶数行的必定两人平分,所以只要抢奇数行中间那个就行了 这题怎么被爆破了 //quming #include<bits/st ...

  6. [Educational Codeforces Round 16]D. Two Arithmetic Progressions

    [Educational Codeforces Round 16]D. Two Arithmetic Progressions 试题描述 You are given two arithmetic pr ...

  7. Dirichlet's Theorem on Arithmetic Progressions 分类: POJ 2015-06-12 21:07 7人阅读 评论(0) 收藏

    Dirichlet's Theorem on Arithmetic Progressions Time Limit: 1000MS   Memory Limit: 65536K Total Submi ...

  8. 洛谷P1214 [USACO1.4]等差数列 Arithmetic Progressions

    P1214 [USACO1.4]等差数列 Arithmetic Progressions• o 156通过o 463提交• 题目提供者该用户不存在• 标签USACO• 难度普及+/提高 提交 讨论 题 ...

  9. Codechef April Challenge 2019 游记

    Codechef April Challenge 2019 游记 Subtree Removal 题目大意: 一棵\(n(n\le10^5)\)个结点的有根树,每个结点有一个权值\(w_i(|w_i\ ...

随机推荐

  1. 【BZOJ2226】[Spoj 5971] LCMSum 莫比乌斯反演(欧拉函数?)

    [BZOJ2226][Spoj 5971] LCMSum Description Given n, calculate the sum LCM(1,n) + LCM(2,n) + .. + LCM(n ...

  2. 清空javascript数组数据

    var arrayObj = new Array(); arrayObj.splice(0, arrayObj.length);//清空数组数据

  3. 邱老师玩游戏(树形DP) UESTC - 1136

    邱老师最近在玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中邱老师允许攻克M个城堡并获得里面的宝物. 但由于地理位置原因,有些城堡不能直接攻克,要攻克这些城堡必须先攻克其 ...

  4. influxDB概念

    一.基本概念 1)database--数据库,这个同传统数据库的数据库概念. 2)measurement--数据表,在InfluxDB中,measurement即为表的作用,同传统数据库中的table ...

  5. Adjacency List

    w Python Patterns - Implementing Graphs | Python.orghttps://www.python.org/doc/essays/graphs/ Graph ...

  6. Markov Process

    w Markov Process -- from Wolfram MathWorld  http://mathworld.wolfram.com/MarkovProcess.html 谷歌背后的数学_ ...

  7. 【22,23节】Django的GET和POST属性笔记

    COOKIES:一个标准的python字典对象,包含所有cookies,键和值都为字符串session:一个即能读又能写的类似字典对象,表示当前的会话,只有当django启用会话的支持时才可用 一键多 ...

  8. Sql多条件排序

    多条件排序可以通过在order by语句后面使用case when then条件语句来实现. end 例子: 1.创建表case_test 共有id,case_type,case_location,c ...

  9. Python之迭代器和生成器(Day17)

    一.可迭代对象(iterable) 刚才说过,很多容器都是可迭代对象,此外还有更多的对象同样也是可迭代对象,比如处于打开状态的files,sockets等等.但凡是可以返回一个迭代器的对象都可称之为可 ...

  10. $Eclipse+Tomcat搭建本地服务器并跑通HelloWorld程序

    本文结构:(一)环境准备(二)在Eclipse里创建Dynamic Web工程(三)写一个简单的Servlet类并配置web.xml(四)运行程序 (一)环境准备 1.Eclipse:要使用for J ...