Description
经过一系列的游戏之后,你终于迎来了今天的作业,第一个作业是预习一个超级美好的函数f(x),描述如下。
为了研究这个函数的性质,你决定定义一次变化为x=f(x)。
若x就经过若干次变化为k,则你就会觉得这是一个k变变数。
现在既然你已经这么觉得了,那就只好给定A,B,求有多少个A<=x<=B是k变变数了。
Input
输入包含三行。
第一行为一个整数k。
第二行为一个整数A。
第三行为一个整数B。
Output
输出仅一行,表示答案。
Sample Input
Sample Input 1
13
12345
67890123
Sample Input2
1
234567
1234567
Sample Output
Sample Output1
8387584
Sample Output2
1000001
Data Constraint
Hint
对于50%的数据,0<=k,A,B<=10^6
对于100%的数据,0<=k,A,B<=10^18 A<=B
Solution
通过找规律可以发现:
1.若一个数x是奇数,那么能通过变换得到这个数的数是 x+1,x*2,x*2+1,x*4,x*4+1,x*4+2,x*4+3,x*8,x*8+1,x*8+2,x*8+3,x*8+4,x*8+5,x*8+6,x*8+7......
2.若x是偶数,那么能通过变换得到这个数的数是x*2,x*2+1,x*2+2,x*2+3,x*4,x*4+1,x*4+2,x*4+3,x*4+4,x*4+5,x*4+6,x*4+7,x*8,x*8+1......
注意要特判0的情况直接等于b-a+1
Code
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
ll k,a,b,ans=0;
void work(ll x,ll m){
while(x<=b){
if(x+m-1>=a){
ans+=x+m-a;
if(x>a) ans-=(x-a);
if(x+m-1>b) ans-=x+m-1-b;
}
x*=2;
m*=2;
}
}
int main(){
scanf("%lld%lld%lld",&k,&a,&b);
if(!k){ans=b-a+1;}
else if(k&1) work(k,1);
else{
if(k+1>=a&&k+1<=b) ans++;
work(k*2,4);
}
printf("%lld\n",ans);
/*f[1]=k;int i=0,j=1;
while(i<j){
i=(i+1)%10000000;
int x=f[i];
if(x>=a) ans++;
if(x*2<=b) f[j=(j+1)%10000000]=x*2;
if(x%2==0&&x+1<=b) f[j=(j+1)%10000000]=x+1;
}*/
for(int k=12;k<=13;k++){
for(int i=1;i<=700;i++){
bool bz=0;
int x=i;
while(x){
x=(x&1)?x-1:x/2;
if(x==k){
bz=1;
break;
}
}
if(!bz) continue;
printf("%d ",i);
}
printf("\n");printf("\n");printf("\n");
}
return 0;
}
作者:zsjzliziyang
QQ:1634151125
转载及修改请注明
本文地址:https://blog.youkuaiyun.com/zsjzliziyang/article/details/86618669