题解:CF201E Thoroughly Bureaucratic Organization
一道能让边哥都说有难度的 adhoc 好题。核桃哪位大神把这个 *2600 放 S 组模拟赛 T2 的啊。
考虑如何区分两个人,显然如果存在一次询问,使得其中一个人在返回的集合中,而另一个人不在返回的集合中,那么这两个人是不同的。
继续考虑如何由此确定编号。我们考虑数学归纳法,先找出编号是
至此原问题被转化为:找出一个最小的
最小的
首先发现先把
那么我们对于
为什么不会出现
最后证明 check 的复杂度,注意到求答案的式子是
#include <bits/stdc++.h>
#define fi first
#define se second
#define eb(x) emplace_back(x)
#define pb(x) push_back(x)
#define lc(x) (tr[x].ls)
#define rc(x) (tr[x].rs)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
using pi=pair<int,int>;
ll n,m;
ll check(ll k)
{
ll lst=m*k,res=1,ad=1;
for(ll i=1;i<=k;i++)
{
ad=ad*(k-i+1)/i;
if(lst-ad*i>0)
{
lst-=ad*i;
res+=ad;
}
else
{
res+=lst/i;
break;
}
if(res>=1000000000)return 1000000000;
}
return res;
}
void solve()
{
cin>>n>>m;
ll l=0,r=n,mid;
while(l<r)
{
mid=(l+r)>>1;
if(check(mid)>=n)r=mid;
else l=mid+1;
}
cout<<l<<'\n';
}
int main()
{
//freopen("sample.in","r",stdin);
//freopen("sample.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
cin>>t;
while(t--)solve();
return 0;
}