1 条题解
-
0
题意:求且满足的的对数。
显然很不好做,我们需要转化一下。
我们发现:
当,有;
当,有。
。
于是:
时,不存在。
所以,即和的位数相同,最高位同时为。
那么问题就转化成,求的的对数。
满足,那么二进制下为,为或,二进制下为,必为。
考虑数位,这种类型的数位不像常规的数位,用的答案减去的答案。
我们考虑枚举哪一位为最高位,然后表示前位,数的大小有没有达到下界,有没有达到上界的方案数,转移时先枚举,再枚举。
还有一道类似的题,做法是相同的。
#include<bits/stdc++.h> #define ts cout<<"ok"<<endl #define int long long #define hh puts("") #define pc putchar #define mo 1000000007 //#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) //char buf[1<<21],*p1=buf,*p2=buf; using namespace std; const int N=65; int l,r,lenl,lenr,pl[N],pr[N],dp[N][2][2],ans; inline int read(){ int ret=0,ff=1;char ch=getchar(); while(!isdigit(ch)){if(ch=='-') ff=-1;ch=getchar();} while(isdigit(ch)){ret=ret*10+(ch^48);ch=getchar();} return ret*ff; } void write(int x){if(x<0){x=-x,pc('-');}if(x>9) write(x/10);pc(x%10+48);} void writeln(int x){write(x),hh;} void writesp(int x){write(x),pc(' ');} int dfs(int pos,int x1,int x2){ if(!pos) return 1; if(dp[pos][x1][x2]!=-1) return dp[pos][x1][x2]; int &res=dp[pos][x1][x2];res=0; int t1=x1?pl[pos]:0,t2=x2?pr[pos]:1; for(int y=t1;y<=t2;y++) for(int x=t1;x<=y;x++) res=(res+dfs(pos-1,x1&(x==t1),x2&(y==t2)))%mo; return res; } signed main(){ memset(dp,-1,sizeof(dp)); l=read(),r=read(); while(l){ pl[++lenl]=l&1; l>>=1; } while(r){ pr[++lenr]=r&1; r>>=1; } for(int i=lenl;i<=lenr;i++) ans=(ans+dfs(i-1,i==lenl,i==lenr))%mo;//枚举哪个最高位为1 write(ans); return 0; }
- 1
信息
- ID
- 11728
- 时间
- 2000ms
- 内存
- 1024MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者