给一个数m,求所有满足C(n,k)==m的二元组(n,k)
由组合数的对称性,如果只算左边,k<=27,另一半对称可得
还有个爆long long的问题,取个上界即可
同学算了上界,直接拿来用
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct P
{
ll n, k;
P(){}
P(ll _n, ll _k){n = _n; k = _k;}
};
bool operator < (P a, P b)
{
if(a.n != b.n) return a.n < b.n;
return a.k < b.k;
}
ll C(ll n, ll k)
{
ll res = 1;
for(int i = 1; i <= k; i++)
res = res * (n - i + 1) / i;
return res;
}
int main()
{
ll f[30]={0,1e15,5e7,2e5,13000,2700,950,500,300,200,150,120,100,90,80,72,67,63,61,60,60,60,55,55,55,55,55,55,55,55};
int T;
scanf("%d", &T);
while(T--)
{
ll M;
scanf("%lld", &M);
vector<P> ans;
for(int k = 1; k <= 27; k++)
{
ll l = k, r = f[k];
while(l != r)
{
ll m = (l + r) >> 1;
if(C(m, k) < M) l = m + 1;
else r = m;
}
if(C(l, k) == M)
{
ans.push_back(P(l, k));
if(l - k > 27)
ans.push_back(P(l, l - k));
}
}
sort(ans.begin(), ans.end());
printf("%d\n", ans.size());
for(int i = 0; i < ans.size(); i++)
printf("(%lld,%lld) ", ans[i].n, ans[i].k);
printf("\n");
}
return 0;
}