• [bzoj1223] [HNOI2002]Kathy函数


      首先由题解可得TAT,f(i)=i当且仅当i在二进制下为回文串。

      那么问题就变成了1~n中有多少个二进制下的回文串。

      把m转成2进制后就是正常的统计了= =。

      f[i]表示二进制下,有多少个i位的回文串(包括前导0)。f[1]=f[2]=2,f[i]=f[i-2]*2.....也就是f[i]=2^((i+1)/2)

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define ri register int
     6 using namespace std;
     7 const int modd=1000000000;
     8 char s[103];
     9 int two[340][20];
    10 int a[20],l[340],len,len2,mp[340],ten[10];
    11 int i,j,k,n,m;
    12 int ans[20],ansl;
    13  
    14 inline bool notsmall(int x){
    15     if(l[x]!=len)return l[x]>len;
    16     for(ri i=len;i;i--)if(two[x][i]!=a[i])return two[x][i]>a[i];
    17     return 1;
    18 }
    19 inline bool notbig(int x){
    20     if(l[x]!=len)return l[x]<len;
    21     for(ri i=len;i;i--)if(two[x][i]!=a[i])return two[x][i]<a[i];
    22     return 1;
    23 }
    24 inline void add(int x){
    25     l[x]=l[x-1];int y=x-1;
    26     for(ri i=1;i<=l[x];i++){
    27         two[x][i]+=two[y][i]<<1;
    28         if(two[x][i]>=modd)two[x][i]-=modd,two[x][i+1]++;
    29     }
    30     if(two[x][l[x]+1])l[x]++;
    31 }
    32 inline void addtoans(int x){
    33     for(ri i=1;i<=l[x];i++){
    34         ans[i]+=two[x][i];
    35         if(ans[i]>=modd)ans[i+1]++,ans[i]-=modd;
    36     }
    37     while(ans[ansl+1])ansl++;
    38 }
    39 inline void dec(int x){
    40     for(ri i=1;i<=l[x];i++){
    41         a[i]-=two[x][i];
    42         if(a[i]<0)a[i]+=modd,a[i+1]--;
    43     }
    44     while(!a[len]&&len>1)len--;
    45 }
    46 inline void run(){
    47     ri i,j,k,len;
    48     two[1][l[1]=1]=1;
    49     for(i=1;!notsmall(i);)i++,add(i);
    50     for(;i;i--)
    51         if(notbig(i))dec(i),mp[i]=1,len2=max(len2,i);
    52 //    for(i=len2;i;i--)printf(" %d",mp[i]);puts("");
    53     for(i=1;i<len2;i++)addtoans((i+1)>>1);
    54     int flag=3;
    55     for(i=len2>>1;i;i--)swap(mp[i],mp[len2-i+1]);
    56     for(i=2;i<=len2&&flag;i++){
    57         if(mp[i]){
    58             if(i<=(len2>>1))addtoans((len2-(i<<1)+3)>>1);
    59             else{
    60                 if(mp[len2-i+1]==0||len2-i+1==i)addtoans(1);
    61             }
    62         }
    63         if(i>(len2>>1))flag&=(mp[len2-i+1]==mp[i]);
    64     }
    65     if(flag==1||len2==1)addtoans(1);
    66 }
    67 int main(){
    68     scanf("%s",s);j=strlen(s);
    69     for(i=ten[0]=1;i<=9;i++)ten[i]=ten[i-1]*10;
    70     for(i=j-1;i>=0;i--){
    71         if(!k)len++;
    72         a[len]+=(s[i]-'0')*ten[k];
    73         k++;if(k>8)k=0;
    74     }
    75     run();
    76     for(printf("%d",ans[ansl]),i=ansl-1;i>0;i--){
    77         for(j=10;j<modd;j*=10)if(ans[i]<j)putchar('0');
    78         printf("%d",ans[i]);
    79     }puts("");
    80     return 0;
    81 }
    View Code

    代码又丑又慢>_<

  • 相关阅读:
    在线制作流程图
    表格设计有感
    mvp需要加上单利模式
    2015.7.17( NOI2015 day1 )
    BZOJ 2073: [POI2004]PRZ( 状压dp )
    1688: [Usaco2005 Open]Disease Manangement 疾病管理( 枚举 )
    BZOJ 1072: [SCOI2007]排列perm( )
    BZOJ 1475: 方格取数( 网络流 )
    BZOJ 3524: [Poi2014]Couriers( 主席树 )
    BZOJ 1087: [SCOI2005]互不侵犯King( 状压dp )
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5253731.html
Copyright © 2020-2023  润新知