日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

【CC November Challenge 2012】Arithmetic Progressions【分块】【FFT】

發(fā)布時(shí)間:2023/12/4 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【CC November Challenge 2012】Arithmetic Progressions【分块】【FFT】 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題意:給定長(zhǎng)度為 nnn 的正整數(shù)序列 AAA,求滿足 i<j<k,Aj?Ai=Ak?Aji<j<k,A_j-A_i=A_k-A_ji<j<k,Aj??Ai?=Ak??Aj? 的三元組個(gè)數(shù)。

n≤105,Ai≤3×104n\leq 10^5,A_i\leq 3\times 10^4n105,Ai?3×104

三個(gè)位置只有 jjj 限制比較緊,“前后各找一個(gè)數(shù)差相同”顯然比“往一個(gè)方向找一個(gè)數(shù)再找一個(gè)數(shù)差相同”容易得多??紤]計(jì)算每個(gè)位置作為 jjj 的貢獻(xiàn)。

我們相當(dāng)于要在前后各找一個(gè)數(shù) x,yx,yx,y,使得 x+y=2akx+y=2a_kx+y=2ak?。

這是個(gè)卷積形式,如果對(duì)每個(gè) kkk 快速搞出 (∑i=1k?1xai)(∑i=k+1nxai)(\sum_{i=1}^{k-1}x^{a_i})(\sum_{i=k+1}^nx^{a_i})(i=1k?1?xai?)(i=k+1n?xai?) 就可以統(tǒng)計(jì)答案了。

但每個(gè)位置都要做 IDFT ,顯得浪費(fèi)??紤]分塊。

設(shè)塊長(zhǎng)為 BBB,維護(hù)前面的塊和后面的塊的值域桶。暴力三元組里當(dāng)前塊有兩個(gè)的,然后前面后面 FFT 乘起來(lái),統(tǒng)計(jì)塊內(nèi)每個(gè)點(diǎn)作為中間位置的貢獻(xiàn)。

這樣復(fù)雜度是 O(NB(B2+Alog?A))\Omicron\left(\frac NB(B^2+A\log A)\right)O(BN?(B2+AlogA)),取 B∈O(Alog?A)B\in \Omicron(\sqrt{A\log A})BO(AlogA?) 后總復(fù)雜度 O(NAlog?A)\Omicron(N\sqrt{A\log A})O(NAlogA?),可以通過(guò)。

#include <iostream> #include <cstdio> #include <cstring> #include <cctype> #include <cmath> #define MAXN 100005 #define double long double using namespace std; typedef long long ll; inline int read() {int ans=0;char c=getchar();while (!isdigit(c)) c=getchar();while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();return ans; } const double Pi=acos(-1.0); const int B=700; struct complex{double x,y;inline complex(const double& x=0,const double& y=0):x(x),y(y){}}; inline complex operator +(const complex& a,const complex& b){return complex(a.x+b.x,a.y+b.y);} inline complex operator -(const complex& a,const complex& b){return complex(a.x-b.x,a.y-b.y);} inline complex operator *(const complex& a,const complex& b){return complex(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);} inline complex adj(const complex& a){return complex(a.x,-a.y);} int l=16,lim=1<<l,r[MAXN]; inline void init(){for (int i=0;i<lim;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));} complex rt[2][20]; void fft(complex* a,int type) {for (int i=0;i<lim;i++) if (i<r[i]) swap(a[i],a[r[i]]);for (int L=0;L<l;L++){int mid=1<<L,len=mid<<1;complex Wn=rt[type][L+1];for (int s=0;s<lim;s+=len){complex w(1,0);for (int k=0;k<mid;k++,w=w*Wn){complex x=a[s+k],y=w*a[s+mid+k];a[s+k]=x+y,a[s+mid+k]=x-y;}}}if (type) for (int i=0;i<lim;i++) a[i].x/=lim,a[i].y/=lim; } int a[MAXN],pre[MAXN],suf[MAXN],cnt[MAXN]; complex F[MAXN]; int main() {init();for (int i=0;i<20;i++){double a=2*Pi/(1<<i);rt[1][i]=adj(rt[0][i]=complex(cos(a),sin(a)));}int n=read();for (int i=0;i<n;i++) a[i]=read();ll ans=0;for (int i=0;i<n;i++) ++suf[a[i]];for (int T=0;T<=n/B;T++){int l=T*B,r=min((T+1)*B,n)-1;for (int i=l;i<=r;i++) --suf[a[i]];for (int i=l+1;i<r;i++){for (int j=l;j<i;j++) ++cnt[a[j]];for (int j=i+1;j<=r;j++) ans+=cnt[2*a[i]-a[j]];for (int j=l;j<i;j++) cnt[a[j]]=0;}for (int i=l;i<r;i++)for (int j=i+1;j<=r;j++){if (2*a[j]>a[i]) ans+=suf[2*a[j]-a[i]];if (2*a[i]>a[j]) ans+=pre[2*a[i]-a[j]];}for (int i=0;i<lim;i++) F[i]=complex(pre[i],suf[i]);fft(F,0);for (int i=0;i<lim;i++) F[i]=F[i]*F[i];fft(F,1);for (int i=l;i<=r;i++) ans+=F[2*a[i]].y/2+0.5;for (int i=l;i<=r;i++) ++pre[a[i]];}cout<<ans;return 0; }

總結(jié)

以上是生活随笔為你收集整理的【CC November Challenge 2012】Arithmetic Progressions【分块】【FFT】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。