首页 > 编程知识 正文

二项项式无理数系数和,系数与二次项式系数

时间:2023-05-05 15:50:20 阅读:235050 作者:263

题目描述
  二项式定理(英语:Binomial theorem),又称cxdcb二项式定理,由艾萨克•cxdcb于1664年、1665年期间提出。该定理给出两个数之和的整数次幂诸如 展开为类似 项之和的恒等式。二项式定理可以推广到任意实数次幂,即广义二项式定理。二项式定理可以用以下公式表示:
   
  我们称C(n,k)为二项式系数。

  现在,你要解决得问题是:已知某二项数系数为m,那么有多少个(n,k)满足(C(n,k)=m,按照n升序排列,若n相同,则按k升序排列。


输入

  第一行为整数T,表示数据组数。接下来的T行,每组数据占一行,为一个整数m。

输出

  每组数据输出两行,第一行为满足条件的(n,k)的数,接下来一行为满足条件的(n,k)对,每队用括号括起来,括号之间用一个空格分开。按n升序排列,若n相同,则按k升序排列。

提示

2<=m<=10^15



分析:

这题刚拿到无从下手,一想反正是练习题时间充足,就找了两三个小时的规律,无奈太弱没找出来....

于是只有通过正当途径找。因为没有找到规律,且这种已知结果求组合数的n,k的问题也没有涉及过,所以枚举什么的应该是无法避免了。

但可以睿智地枚举。首先不要枚举n。因为一旦m大了之后,n的枚举范围可能会异常大,不明智。相对来说k就好枚举多了,根据二项式定理的推论,C(n,n/2)最大,C(n,1)最小。此处k固定,那么n=2*k是最小的二分范围,n=m是最大的二分范围。于是,k通过for循环枚举,每枚举一个k就二分找n。

注意枚举k时也可以加一个判断,如果C(2*k,k)比m还大,说明n取最小的时候都已经无解了,就直接退出。

检查n是否正确:直接计算,因为组合数除掉的数始终比乘上的数小,所以一旦中间结果大于m就直接返回m+1表示不成立。

另:最多的有8对...


#include<cstdio>#include<algorithm>#include<cmath>using namespace std;typedef long long LL;int T;LL M,tot;struct data{LL N,K;}ans[10];bool cmp(data a,data b) {return a.N==b.N?a.K<b.K:a.N<b.N;}LL check(LL n,LL m){LL a=1;for(int i=1;i<=m;i++){if(a/i>M/(n-i+1)) return M+1;a*=(n-i+1);a/=i;}return a;}void solve(){tot=0;LL l,r,mid,t;for(LL k=1;check(k*2,k)<=M;k++){l=2*k,r=M;while(r>=l){mid=(r+l)/2;t=check(mid,k);if(t==M){ans[++tot]=(data){mid,k};if(mid!=k*2) ans[++tot]=(data){mid,mid-k};break;}else if(t>M) r=mid-1;else l=mid+1;}}}int main(){//freopen("in.txt","r",stdin);scanf("%d",&T);while(T--){scanf("%lld",&M);solve();if(tot) sort(ans+1,ans+1+tot,cmp);printf("%dn",tot);for(int i=1;i<=tot;i++) {printf("(%lld,%lld)",ans[i].N,ans[i].K);if(i!=tot) printf(" ");}if(T) printf("n");}return 0;}

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。