jzoj6065-[NOI2019模拟2019.3.18]One?One!【FFT】
正題
題目鏈接:https://gmoj.net/senior/#main/show/6065
題目大意
oneness(x)oneness(x)oneness(x)表示xxx的約數(shù)中全是111的數(shù)的個數(shù),給出一個長度為lll的隨機生成的數(shù)nnn,求∑i=1noneness(i)\sum_{i=1}^noneness(i)i=1∑n?oneness(i)
解題思路
轉(zhuǎn)換一下題意就是求∑i=2l?n10i?19?=∑i=2l?9n10i?1?\sum_{i=2}^l\lfloor\frac{n}{\frac{10^i-1}{9}}\rfloor=\sum_{i=2}^l\lfloor\frac{9n}{10^i-1}\rfloori=2∑l??910i?1?n??=i=2∑l??10i?19n??
先讓nnn乘上999,然后把每一位的貢獻拆成小數(shù)和整數(shù)部分,我們先來看整數(shù)部分
首先對于一個k?10i10j?1\frac{k*10^i}{10^j-1}10j?1k?10i?那么它的值應該是在第i?xj+1(x∈N)i-xj+1(x\in N)i?xj+1(x∈N)位會有一個kkk。(如109999=1001001.001001001001001001001001\frac{10^9}{999}=1001001.001001001001001001001001999109?=1001001.001001001001001001001001)
然后我們看這題,jjj是1~n1\sim n1~n的每一個值,那么對于每第iii位我們拆成k?10ik*10^ik?10i會對第i?xi-xi?x位產(chǎn)生σ0(x)\sigma_0(x)σ0?(x)次貢獻(σ0(x)\sigma_0(x)σ0?(x)表示xxx的約數(shù)個數(shù))。設aia_iai?表示第iii位的數(shù),fif_ifi?表示第iii位的答案,那么有式子fi=∑j=0∞ai+jσ0(j)f_i=\sum_{j=0}^{\infty}a_{i+j}\sigma_0(j)fi?=j=0∑∞?ai+j?σ0?(j)
這個式子可以先預處理出σ0(j)\sigma_0(j)σ0?(j)然后把aaa反過來就是一個卷積的式子,FFTFFTFFT優(yōu)化即可。
對于小數(shù)部分,因為在比較后的位數(shù)的產(chǎn)生貢獻概率極小,又因為數(shù)字隨機生成,所以我們直接將這些部分省略。我們只處理到小數(shù)的121212位,和上面同理算出每一個小數(shù)位的貢獻即可。
時間復雜度O(nlog?n)O(n\log n)O(nlogn)
codecodecode
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<cstdlib> #define ll long long using namespace std; const ll N=1e6+10; const double Pi=acos(-1); struct complex{double x,y;complex(double xx=0,double yy=0){x=xx;y=yy;return;} }x[N],y[N]; ll n,m,r[N],a[N],d[N],b[N],f[N]; unsigned int sed; complex operator+(complex x,complex y) {return complex(x.x+y.x,x.y+y.y);} complex operator-(complex x,complex y) {return complex(x.x-y.x,x.y-y.y);} complex operator*(complex x,complex y) {return complex(x.x*y.x-x.y*y.y,x.x*y.y+x.y*y.x);} void fft(complex *f,ll op){for(ll i=0;i<m;i++)if(i<r[i])swap(f[i],f[r[i]]);for(ll p=2;p<=m;p<<=1){ll len=p>>1;complex tmp(cos(Pi/len),op*sin(Pi/len));for(ll k=0;k<m;k+=p){complex buf(1,0);for(ll i=k;i<k+len;i++){complex tt=f[i+len]*buf;f[i+len]=f[i]-tt;f[i]=f[i]+tt;buf=buf*tmp;}}}return; } void solve(){m=1;ll lg=0;for(;m<=2*n;m<<=1);for(ll i=0;i<=m;i++)r[i]=(r[i>>1]>>1)|((i&1)?(m>>1):0);for(ll i=1;i<=n;i++)x[i]=complex(a[n-i+1],0),y[i]=complex(d[i],0);fft(x,1);fft(y,1);for(ll i=0;i<m;i++)x[i]=x[i]*y[i];fft(x,-1);for(ll i=0;i<m;i++)f[i]=(int)(x[i].x/(double)m+0.5);return; } int main() {scanf("%lld%u",&n,&sed);for(ll i=1;i<=n;i++){a[i]=sed/1024%10;sed=sed*747796405u-1403630843u;}reverse(a+1,a+n+1);ll g=0;for(ll i=1;i<=n;i++){a[i]=a[i]*9+g;g=a[i]/10;a[i]%=10;}if(g)a[++n]=g;for(ll i=2;i<=n;i++)for(ll j=i;j<=n;j+=i)d[j]++;solve();reverse(f+1,f+n+1);ll pw[11];pw[0]=1;for(ll i=1;i<=10;i++)pw[i]=pw[i-1]*10;for(ll i=2;i<=10;i++){ll S=0;for(ll j=1;j<=n;j+=i)for(ll k=1;k<=i;k++)S+=a[j+k-1]*pw[k-1];f[1]+=S/(pw[i]-1); }for(ll i=11;i<=n;i++){for(ll j=1;j<=12;j++)b[j]=0;for(ll j=1;j<=n;j+=i)for(ll k=1;k<=11;k++)b[k]+=a[j+i+k-12];for(ll j=1;j<=11;j++){b[j+1]+=b[j]/10;b[j]%=10;}f[1]+=b[12];}for(ll i=1;i<=n;i++){f[i+1]+=f[i]/10;f[i]%=10;}while(!f[n])n--;while(n)printf("%lld",f[n--]);return 0; }總結(jié)
以上是生活随笔為你收集整理的jzoj6065-[NOI2019模拟2019.3.18]One?One!【FFT】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ATcoder-[AGC048B]Bra
- 下一篇: 装机配置清单(求一套电脑配置)