100729 A 解题报告
链接链接http://codeforces.com/gym/100729/attachments/download/3754/20112012-northwestern-european-regional-contest-nwerc-2011-en.pdf
题意:给你n
求出所有的C(m,k)=n
这一题..n<=10^15
所以做法就比较有趣了
首先就是可以得到一个规律
C的增长相当快,C(100,10)=17,310,309,456,440 > 1e15
那么我们可以考虑
对于k=1到10的时候,分别枚举,二分,求出一个对应的k
如果对于同一个n而言(n>100),k的增大(<50的情况下)只会让值变得更大
那么我们只要知道k在11~n-11之间几乎(好像也是完全)无解的
那么只要暴力枚举以后二分出m即可,注意去重
代码如下:
#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<string>
#include<math.h>
#include<time.h>
#include<vector>
#include<bitset>
#include<memory>
#include<utility>
#include<fstream>
#include<stdio.h>
#include<sstream>
#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct answer
{
long long x;
long long y;
friend bool operator < (const answer &a,const answer &b)
{
if (a.y!=b.y) return a.y<b.y;
return a.x<b.x;
}
friend bool operator == (const answer &a,const answer &b)
{
return !((a<b)||(b<a));
}
void output()
{
cout<<"("<<y<<","<<x<<") ";
}
};
answer ans[10005];
long long c[105][105];
long double check(long long x,int y)
{
int i;
long double t=0;
for (i=1;i<=y;i++)
{
t+=log10((long double)(x+1-i));
t-=log10((long double)i);
}
return t;
}
long long cc(long long x,int y)
{
int i;
long long t=1;
for (i=1;i<=y;i++)
{
t*=(x+1-i);
t/=i;
}
return t;
}
int main()
{
#ifdef absi2011
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
#endif
int t;
scanf("%d",&t);
int zu;
int i,j;
c[0][0]=1;
for (i=1;i<=100;i++)
{
c[i][0]=1;
for (j=1;j<=100;j++)
{
c[i][j]=c[i-1][j-1]+c[i-1][j];
if (c[i][j]>10000000000000000ll) c[i][j]=10000000000000000ll;
}
}
for (zu=0;zu<t;zu++)
{
long long n;
cin>>n;
int i,j;
int sum=0;
for (i=0;i<=100;i++)
{
for (j=0;j<=100;j++)
{
if (c[i][j]==n)
{
ans[sum].x=j;
ans[sum].y=i;
sum++;
}
}
}
for (i=1;i<=10;i++)
{
long long l=i,r=n;
for (;l<=r;)
{
long long mid=(l+r)/2;
if (check(mid,i)<=log10((long double)n))
{
l=mid+1;
}
else
{
r=mid-1;
}
}
long long t=cc(r,i);
if (t==n)
{
ans[sum].x=i;
ans[sum].y=r;
sum++;
ans[sum].x=r-i;
ans[sum].y=r;
sum++;
}
t=cc(l,i);
if (t==n)
{
ans[sum].x=i;
ans[sum].y=l;
sum++;
ans[sum].x=l-i;
ans[sum].y=l;
sum++;
}
}
sort(ans,ans+sum);
sum=unique(ans,ans+sum)-ans;
cout<<sum<<'\n';
for (i=0;i<sum;i++)
{
ans[i].output();
}
cout<<'\n';
}
return 0;
}
评论 (0)