2719 sheldon数

来源:互联网 发布:seo搜索优化软件 编辑:程序博客网 时间:2024/06/15 11:14

Task
转化为2进制形如ABABAB…。A,B分别代表1,0,长度各自相同的数为sheldon数,且最高位肯定是1。
求它在[ l , r ]区间内的个数。

0<=L<=R<2^63

Solution
70分枚举•十进制
暴力求L,R区间内的数是否符合这个条件。

100分终态枚举•二进制
求区间内的数可以由前缀思想来处理。
Cal( l, r )=Cal( 0, R )-Cal( 0, L-1)
枚举二进制上1,0的个数。用二进制位移来完成数的组合。

ll L,R;int tot;int s[100],far[100];struct P60{    /* 20161030.8 */    inline void chg(int x){        tot=0;s[0]=0;        while(x>0){            s[tot++]=x%2;            x>>=1;        }    }    inline bool check(){        int a,b,num[2];        far[tot-1]=tot-1;        memset(num,-1,sizeof(num));        per(i,tot-2,0){            if(s[i]==s[i+1])far[i]=far[i+1];            else far[i]=i;        }        for(int i=0;i<tot;i=far[i]+1){            if(num[s[i]]==-1)num[s[i]]=far[i]-i+1;            else if(num[s[i]]!=far[i]-i+1)return 0;        }        return 1;    }    inline void solve(){        int l=L,r=R,i,j,k,ans=0;        rep(i,l,r){            chg(i);            if(check())ans++;        }        printf("%d\n",ans);    }}P60;struct P100{    /*  20161030.14  位移*/    ll A[70];//有i个1 的数     int num[2];    inline void init(){        int i;rep(i,1,63)A[i]=A[i-1]<<1|1;    }    inline void print(ll x){        string S="";        while(x){            S+=((x%2)^48);            x>>=1;        }        for(int i=S.size()-1;i>=0;i--)printf("%c",S[i]);puts("");    }    inline ll cal(ll R){//[0,R] 内符合的个数         if(R<=0)return 0;        int i,j,k,cur,tot;        ll x,ans=0;        rep(i,1,63){//有i个1             num[1]=i;            if(A[i]>R)break;            else{//              print(A[i]);                ans++;//没有0的情况             }            rep(j,1,63-i){//有j个0                x=A[i];                num[0]=j;                 tot=i;cur=0;                while(tot+num[cur]<=63){                    tot+=num[cur];                    if(cur==0)x=x<<j;                    else x=x<<i|A[i];                    if(x<=R)ans++;                    else break;                    cur^=1;                }            }        }           return ans;    }    inline void solve(){        init();        printf("%lld\n",cal(R)-cal(L-1));    }}P100;int main(){//  freopen("sheldon2.in","r",stdin);//  freopen("ans.out","w",stdout);    rd(L);rd(R);    if(R<=100000)P60.solve();    else P100.solve();    return 0;}
0 0
原创粉丝点击