zoukankan      html  css  js  c++  java
  • Codeforces Round #608 (Div. 2) E. Common Number

    题目链接:https://codeforces.com/contest/1271/problem/E

    题意:给定函数f(x),x为偶数时f(x)=x/2,x为奇数时f(x)=x-1

    给定n,k,对1到n每个数求f(x)的轨迹,如path[15]={15,14,7,6,3,2,1},求在所有轨迹里出现次数大于等于k的最大值ans。

    以下为轨迹图:n=31时,4在4-5、8-11、16-23中都出现了

    n的大小只能控制最后一层的数目

    当图最后一层完整时,每一层的奇数、偶数出现的次数都相等

    当图最后一层不完整时,每一层较右(较小)的偶数出现次数总是大于较左的偶数出现次数,奇数同理

    所以把奇偶分开来,奇数列和偶数列都呈单调递减态,可以用二分来判断

    求出出现次数大于等于k的最大奇数、最大偶数,再求max

    如何求某个数的出现次数?

    4的次数=(5-4+1)+(11-8+1)+(23-16+1),16为不超过n的最大2的次方,23=11*2+1,11=5*2+1

    需要注意最后一层不一定完整,23、11等只是个理论值,可能会超过n,当其超过n时要取n

    参考自:https://www.cnblogs.com/Herlo/p/12082724.html

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    ll n,k;
    bool check(ll tmp)
    {
        queue<pair<ll,ll> >q;
        if(tmp&1)q.push(make_pair(tmp,tmp));
        else q.push(make_pair(tmp,tmp+1));
        ll ans=0;
        while(q.size())
        {
            auto it=q.front();
            q.pop();
            ans+=min(n,it.second)-it.first+1;
            if((it.first<<1)<=n)q.push(make_pair(it.first<<1,it.second<<1|1));
        }
        return ans>=k;
    }
    int main()
    {
        ll ans=0;
        cin>>n>>k;
        
        ll l=0,r=n/2;
        while(l<=r)
        {
            ll mid=l+r>>1;
            if(check(mid<<1|1))
            {
                ans=max(ans,mid<<1|1);
                l=mid+1;
            }
            else r=mid-1;
        }
        
        l=1,r=n/2;//偶数枚举只能枚因子 
        while(l<=r)
        {
            ll mid=l+r>>1;
            if(check(mid<<1))
            {
                ans=max(ans,mid<<1);
                l=mid+1;
            }
            else r=mid-1;
        }
        cout<<ans<<endl;
        return 0;
    } 

    进阶解法:

    尚未参透

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    ll solve(ll n,ll k)
    {
        ll tmp=1;
        while(tmp<=k)tmp*=2;
        tmp/=2;
        //return (n-k+tmp)/tmp; 
        return 1+(n-k)/tmp;
    }
    int main()
    {
        ll n,k,ans;
        cin>>n>>k; 
        ans=max(solve(n,k),solve(n,k+1)<<1);
        cout<<ans<<endl;
        return 0;
    } 
  • 相关阅读:
    qml 无边框
    Qt 参考链接
    QPushButton QSS
    Head First设计模式之备忘录模式
    Head First设计模式之访问者模式
    Head First设计模式之状态模式
    web打印总结
    Head First设计模式之单例模式
    .Net IOC框架入门之一 Unity
    第五章 MVC之Bundle详解
  • 原文地址:https://www.cnblogs.com/myrtle/p/12162580.html
Copyright © 2011-2022 走看看