Codeforces 477D

来源:互联网 发布:蛤蟆吃创建不了网络 编辑:程序博客网 时间:2024/06/13 05:57

big[i][j][i,j][ij,j]getcnt()getmm()

#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>using namespace std;typedef __int64 LL;const int N=5000+100;const int mod=1e9+7;#define lowbit(x) x&-xconst LL inf=1LL<<50;int big[N][N];LL sum[N],dp[N][N];char ss[N];int n;void getbig(){    for(int i=1;i<=n;i++){        int pre;        for(int j=n-i+1;j>=1;j--){            int k=j-i;            if(k<1){                dp[j][i]=1;continue;            }            if(j==n-i+1){                for(pre=k;pre<j;pre++){                    if(ss[pre]>ss[pre+i]){                        big[j][i]=-1;break;                    }                    if(ss[pre]<ss[pre+i]){                        big[j][i]=1;break;                    }                }                if(pre==j){                    big[j][i]=0;                }                continue;            }            if(ss[k]>ss[j]){                pre=k;big[j][i]=-1;            }            else if(ss[k]<ss[j]){                pre=k;big[j][i]=1;            }            else {                if(pre>=j){                    pre=j;big[j][i]=0;                }                else {                    big[j][i]=big[j+1][i];                }            }        }    }}void getcnt(){    memset(sum,0,sizeof(sum));    for(int i=1;i<=n;i++){        for(int j=1;j<=n-i+1;j++){            if(ss[j]=='0')dp[j][i]=0;            else if(j>1){                if(big[j][i]>=0){                    dp[j][i]=sum[j-1];                }                else dp[j][i]=(sum[j-1]-dp[j-i][i])%mod;            }            else dp[j][i]=1;            sum[j+i-1]+=dp[j][i];sum[j+i-1]%=mod;        }    }    printf("%I64d\n",(sum[n]%mod+mod)%mod);}void getmm(){    for(int i=1;i<=n;i++){        sum[i]=inf;    }    for(int i=1;i<=n;i++){        for(int j=1;j<=n-i+1;j++){            if(ss[j]=='0')dp[j][i]=inf;            else if(j>1){                if(big[j][i]>=0){                    if(j-i>=1)dp[j][i]=min(sum[j-1],dp[j-i][i])+1;                    else dp[j][i]=sum[j-1]+1;                }                else dp[j][i]=sum[j-1]+1;            }            else dp[j][i]=1;        }        for(int j=1;j<=n-i+1;j++){            sum[j+i-1]=min(sum[j+i-1],dp[j][i]);        }    }    LL ans=inf;    LL tmp=1;    LL bns=0;    for(int i=n;i>=1;i--){        bns+=tmp*(ss[i]-'0');        if(bns>ans||tmp>ans)break;        ans=min(ans,bns+dp[i][n-i+1]);        tmp*=2;    }    if(ans!=inf)printf("%I64d\n",ans%mod);    else {        bns=0;tmp=1;        for(int i=n;i>=1;i--){            bns+=tmp*(ss[i]-'0');bns%=mod;            if(dp[i][n-i+1]<=n){                //printf("%d %I64d\n",i,dp[i][n-i+1]);                printf("%I64d\n",(bns+dp[i][n-i+1])%mod);break;            }            tmp*=2;tmp%=mod;        }    }}int main(){    #ifdef DouBi    freopen("in.cpp","r",stdin);    #endif // DouBi    while(scanf("%s",ss+1)!=EOF){        n=strlen(ss+1);        getbig();        getcnt();        getmm();    }    return 0;}
0 0
原创粉丝点击