赞
踩
- #include<bits/stdc++.h>
- using namespace std;
- #define ll long long
-
- ll n;
-
- //二分查找的底部
- //去除全是1的斜列,从左往右数起第i个斜列有:
- //c(buttom[i],i)<=10e9<c(buttom[i]+1,i)
- //写个别的程序跑一遍即可得
- ll buttom[17]={ 0,1000000000,44722,1819,
- 396,167,98,69,
- 54,46,41,38,
- 36,35,34,33,33};
-
- //计算组合数c(a,b),a是下标,b是上标
- ll c(ll a,ll b){
- ll sum=1;
- for(ll i=a,j=1;j<=b;++j,--i){
- sum=sum*i/j;
- if(sum>n)break;
- }
- return sum;
- }
-
- //计算h行第l个数排在第几个
- ll find(ll h,ll l){
- return (1+h)*h/2+l;
- }
-
-
- int main(){
- cin>>n;
- ll ans=0;
-
- //第16斜列有:
- //c(32,16)<10e9<c(33,16)
- //可以提前处理
- if(n==1)ans=1;
- else if(n==601080390)ans=c(32,16);
-
- else{
- //遍历15个斜列
- for(ll i=15;i>=1;--i){
- //二分查找即可
- //我的查找写的好烂。。。
- ll u=2*i;
- ll d=buttom[i];
- ll m=u+d>>1;
- while((d-u)>=2){
- if(c(m,i)<=n)u=m;
- else d=m;
- m=u+d>>1;
- }
- if(c(u,i)==n){
- ans=find(u,i+1);
- //cout<<u+1<<' '<<i+1<<endl;
- break;
- }
- if(c(d,i)==n){
- ans=find(d,i+1);
- //cout<<d+1<<' '<<i+1<<endl;
- break;
- }
- if(c(m,i)==n){
- ans=find(m,i+1);
- //cout<<m+1<<' '<<i+1<<endl;
- break;
- }
- //二分查找结束,进入下一斜列
- }
- }
-
- cout<<ans;
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。