题意:
就是给你一个函数f(x) = x/2(如果x是偶数),f(x) = x-1(如果x是奇数且不为1)。定义path(15) = [15,14,7,6,3,2,1]。也就是他会走的数字直到为1。然后给你一个k,问你哪个数字在>=k个不同的path中出现过,如果有多个,输出最大的那个数。
思考:
代码:
#include
#define fi first
#define se second
#define pb push_back
#define db double
#define int long long
#define PII pair<int,int >
#define mem(a,b) memset(a,b,sizeof(a))
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
using namespace std;
const int mod = 1e9+7,inf = 1e18;
const int N = 2e5+10,M = 2010;
int T,n,m,k;
int get(int x)
{
queue<PII > q;
if(x&1) q.push({x,x}); //这一层的左右区间,奇数就自己
else q.push({x,x+1}); //偶数是两个
int sum = 0;
while(q.size())
{
auto now = q.front();q.pop();
sum += min(n,now.se)-now.fi+1; //这段区间可以加多少数
if(now.fi*2<=n) q.push({now.fi*2,now.se*2+1}); //如果还可以扩展
}
return sum;
}
bool check(int mid)
{
int sum = get(mid);
return sum>=k;
}
signed main()
{
IOS;
cin>>n>>k;
int maxn = 0;
int l = 1,r = n&1?n:n-1; //初始范围
while(l<=r) //l<=r
{
int mid = (l+r)>>1;
if(mid%2==0) mid--; //如果不是奇数-1
if(check(mid))
{
l = mid+2; //+2
maxn = max(maxn,mid); //答案要在这里面更新
}
else r = mid-2; //-2
}
l = 2,r = n&1?n-1:n;
while(l<=r)
{
int mid = (l+r)>>1;
if(mid%2!=0) mid--;
if(check(mid))
{
l = mid+2;
maxn = max(maxn,mid);
}
else r = mid-2;
}
cout<<maxn;
return 0;
}
总结:
多多思考,画图模拟模拟。