[Двудольные] Codeforces 1271E Общий номер

Ссылка на тему

решение проблемы

Легко найти, для данного \ (N \) , предполагая , что \ (Y \) в \ (К \) й отличаются друг от друга \ (path_j \) произошло, то \ ([1, п] \ ) в пределах и существует только \ (\ K) номер, который \ (к \) двоичное число (Y \) \ двоичное префикс, или если \ (Y \) является наименее значащий бит является двоичным \ (0 \) когда, \ (Y \) является наименее значащий бит может ввести \ (1 \) , а затем к \ (Y \) имеет префикс.

Мог бы сделать \ (судьи (х) \) представляет собой \ ([1, N] \ ) внутрь \ (Х \) двоичное число числа префиксов, то есть, было \ (Х \) отличается друг от друга \ (path_j \) число. С тех пор мы \ (х = 1 \) начинают, по- прежнему \ (х \) влево до \ (судья (Х-) <K \) , вы можете получить (Отв \) \ двоичная максимальная длина. Тогда мы имеем это \ (х \) на основе \ (х \) двоичной и десятичной постоянно пытается \ (0 \) становится \ (1 \) , если после изменения \ (судья (х) \) все еще больше , чем \ (к \) , а затем сохранить изменения, или переходите к следующему судье.

Для функций (судья (х-) \) \ , жмем \ (х \) рассчитывается отдельно после добавления числа битов, предположим теперь , что мы хотим \ (х \) добавить длину после \ (Len \) суффикс , мы можем использовать две точки вычисляется длина \ (Len \) максимальное расширение, то есть в \ (Х \) добавляют длину \ (Len \) суффикса, \ ([. 1, N] \) префикс а \ (х \) числа числа.

Код

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;

#define RG register int
#define LL long long

LL N,K;

inline LL f(LL x,LL Len){
    LL L=0,R,Res=0;
    if(x&1) R=(1LL<<Len)-1;
    else R=(1LL<<(Len+1))-1;
    x<<=Len;
    if(x>N) return 0;
    while(L<=R){
        LL mid=(L+R)>>1;
        if(x+mid<=N){Res=mid+1;L=mid+1;}
        else R=mid-1;
    }
    return Res;
}

bool Judge(LL x){
    LL temp=x,Res=0,Len=0;
    while(temp<=N){Res+=f(x,Len);++Len;temp<<=1;}
    if(Res>=K) return true;
    return false;
}

inline LL GetLen(LL x){
    LL Len=0;
    while(x){++Len;x>>=1;}
    return Len-1LL;
}

int main(){
    cin>>N>>K;
    LL Ans=1;
    while(Judge(Ans<<1)) Ans<<=1;
    LL Len=GetLen(Ans);
    for(RG i=Len-1;i>=0;--i)
        if(Judge(Ans+(1LL<<i))) Ans+=(1LL<<i);
    cout<<Ans<<endl;
    return 0;
}

рекомендация

отwww.cnblogs.com/AEMShana/p/12431440.html