第一眼以为是傻逼斜率优化>_<
f[i]表示按i次最多可输出字符数。。f[i]=max{ f[i-1]+1,(i-j-1)*f[j] },j<i-2
结果n在100+的时候就喜闻乐见地爆了longlong
根据网上题解可得(T_T)。。这题大概是要FFT优化?(跟着ccz大爷刷题果然高风险TAT
然而题解表示,这题求出f的前几项后,令x=n%5+15,最终答案f[n]=f[x]*4^((n-x)/5)..........
我死活没看出来这是为啥。。。
我显然是连FFT都不会的傻逼。。只好写了个压位高精度快速幂。。结果跑了#3。。233
突然觉得正解显然不是FFT = =。。另外status里面一堆奇怪语言也是感人>_<
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #define ll long long 5 #define d double 6 using namespace std; 7 const int maxn=1002333; 8 const int modd=1000000000; 9 ll f[233]; 10 int dl[maxn],l,r; 11 ll a[32333],c[32333],b[32333]; 12 int i,j,k,n,m,lena,lenc; 13 14 inline d xl(int k,int j){//k<j<i-2 15 return ( f[j]*(j+1)-f[k]*(k+1) )/ (d)(f[j]-f[k]); 16 } 17 int ra,fh;char rx; 18 inline int read(){ 19 rx=getchar(),ra=0,fh=1; 20 while((rx<'0'||rx>'9')&&rx!='-')rx=getchar(); 21 if(rx=='-')fh=-1,rx=getchar(); 22 while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra*fh; 23 } 24 inline void multoa(){ 25 register int i,j,k; 26 memset(b,0,(lena*2+1)<<3); 27 for(i=1;i<=lena;i++)for(j=1,k=i;j<=lena;j++,k++){ 28 b[k]+=a[i]*a[j]; 29 if(b[k]>=modd)b[k+1]+=b[k]/modd,b[k]%=modd; 30 } 31 for(k=lena<<1;!b[k];k--); 32 memcpy(a,b,(k+1)<<3);lena=k; 33 } 34 inline void multoc(){ 35 register int i,j,k; 36 memset(b,0,(lena+lenc+1)<<3); 37 for(i=1;i<=lena;i++)for(j=1,k=i;j<=lenc;j++,k++){ 38 b[k]+=a[i]*c[j]; 39 if(b[k]>=modd)b[k+1]+=b[k]/modd,b[k]%=modd; 40 } 41 for(k=lena+lenc;!b[k];k--); 42 memcpy(c,b,(k+1)<<3);lenc=k; 43 } 44 inline void poi(int b){//计算4^b 45 c[lenc=1]=1;a[lena=1]=4; 46 while(b){ 47 if(b&1)multoc(); 48 b>>=1; 49 if(b)multoa(); 50 } 51 } 52 53 int main(){ 54 n=read(); 55 f[1]=1,f[2]=2,f[3]=3; 56 l=1,r=0; 57 for(i=4;i<=25;i++){ 58 while(l<r&&xl(dl[r-1],dl[r])>=xl(dl[r],i-3))r--; 59 dl[++r]=i-3; 60 while(l<r&&i>xl(dl[l],dl[l+1]))l++; 61 f[i]=f[dl[l]]*(i-dl[l]-1); 62 if(f[i-1]+1>f[i])f[i]=f[i-1]+1; 63 // printf(" i:%d %lld ",i,f[i]); 64 } 65 if(n<=25)printf("%lld ",f[n]);else{ 66 int x=n%5+15; 67 poi((n-x)/5); 68 a[lena=1]=f[x]; 69 multoc(); 70 for(printf("%lld",c[lenc]),i=lenc-1;i>0;i--){ 71 for(j=modd/10;j;j/=10)if(c[i]<j)putchar('0'); 72 printf("%lld",c[i]); 73 }puts("");//printf(" %d ",lenc); 74 } 75 return 0; 76 }