zoukankan      html  css  js  c++  java
  • 【JZOJ3084】超级变变变【模拟】【规律】

    题目大意:

    题目链接:https://jzoj.net/senior/#main/show/3084
    求在LRLsim R中,有多少个数字经过若干次变化会转变为kk。这个变化方式如下:
    在这里插入图片描述


    思路:

    这种题目大部分都是有规律的。所以可以先打一个搜索求出12001sim 200中能变化成kk的表。
    然后就能发现规律如下:

    • 对于任意一个偶数kk,若一个数xx满足在k×2y+t(y=0Inf,t=022y)k imes 2^y+t(y=0sim Inf,t=0sim2^{2y})
      ,则xx能经过变换得到kk
    • 对于任意一个奇数kk,若一个数xx满足在k×2y+t(y=0Inf,t=02y)k imes 2^y+t(y=0sim Inf,t=0sim2^y),则xx能经过变换得到kk

    所以就用模拟求出答案即可。
    时间复杂度O(log B)O(log B)


    代码:

    #include <cstdio>
    #include <iostream>
    using namespace std;
    typedef long long ll;
    
    ll l,r,ans,k,num=1;
    
    int main()
    {
    	cin>>k>>l>>r;
    	if (r<k) return !printf("0
    ");
    	if (!k) return !printf("%d
    ",r-l+1);  //特判
    	if (k&1)
    	{
    		while (k*num+num-1<l) num*=2;
    		if (k*num>r) return !printf("0
    ");
    		if (k*num>=l) ans+=num;
    			else ans+=k*num+num-l;
    		num*=2;
    		while (k*num+num-1<=r)
    		{
    			ans+=num;
    			num*=2;
    		}
    		if (k*num<=r) ans+=r-k*num+1;
    	}
    	else
    	{
    		if (k+1>=l&&k+1<=r) ans++;
    		while (k*num+num*2-1<l) num*=2;
    		if (k*num>r) return !printf("0
    ");
    		if (k*num>=l) ans+=num*2;
    			else ans+=k*num+num*2-l;
    		num*=2;
    		while (k*num+num*2-1<=r)
    		{
    			ans+=num*2;
    			num*=2;
    		}
    		if (k*num<=r) ans+=r-k*num+1;
    	}
    	cout<<ans;
    	return 0;
    }
    
  • 相关阅读:
    《实例化需求》
    《编写有效用例》
    Alpha版总结会议
    团队开发冲刺第二阶段11
    团队开发冲刺第二阶段10
    团队开发冲刺第二阶段9
    团队开发冲刺第二阶段8
    团队开发冲刺第二阶段7
    团队开发冲刺第二阶段6
    团队开发冲刺第二阶段5
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998374.html
Copyright © 2011-2022 走看看