[jzoj 3084] 超级变变变 {推理}

题目

Description
经过一系列的游戏之后,你终于迎来了今天的作业,第一个作业是预习一个超级美好的函数f(x),描述如下。
在这里插入图片描述
为了研究这个函数的性质,你决定定义一次变化为x=f(x)。
若x就经过若干次变化为k,则你就会觉得这是一个k变变数。
现在既然你已经这么觉得了,那就只好给定A,B,求有多少个A<=x<=B是k变变数了。

Input
输入包含三行。
第一行为一个整数k。
第二行为一个整数A。
第三行为一个整数B。

Output
输出仅一行,表示答案。


解题思路

打表找规律
f ( x ) = ⌈ x 2 a ⌉ f(x)=\left \lceil \frac{x}{2a} \right \rceil f(x)=2ax
⌊ x 2 n ⌋ = k \left \lfloor \frac{x}{2n} \right \rfloor=k 2nx=k
对于n我们可以枚举,并累计2^{n}的个数。
然后我们可以求出1~ B再减去1~A-1的数。


代码

#include<cstdio>
#define ll long long
using namespace std;
ll k,a,b,ans; 
ll get(ll x)
{
    if (k<=1) return x; 
    ll z=1,ret=0; 
    while (z*k<=x){
    	ret+=z; 
    	if (z*k+z-1>x) ret-=z*k+z-1-x; 
    	z*=2; 
	}
	return ret; 
}
int main()
{
    scanf("%lld%lld%lld",&k,&a,&b);
    ans+=get(b)-get(a-1); 
    if (k&&!(k&1)) k++,ans+=get(b)-get(a-1); 
    printf("%lld",ans);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值