codevs 5118 , Wjj的视频2 , 高精度

来源:互联网 发布:ogame源码 编辑:程序博客网 时间:2024/06/05 18:42

http://codevs.cn/problem/5118/

题目描述 Description

Wjj又给她的妹子们拍了很多视频。为了拍摄这些视频,并保证视频的清晰度,让每一根毛都能看得清清楚楚,他还特意去买了一张32TB的内存卡。

当Wjj准备用你之前给他写的编号程序给新拍的视频编号时,程序出了错误。

现在,Wjj非常生气,他要你立刻写出正确的程序,并给所有新的视频编好号。


编号的方式和之前相同。第1个视频编号是1;第2、3个视频编号是2,4;第4、5、6个视频编号是5,7,9;接下来四个的编号是10,12,14,16;以此类推。现在Wjj拍摄了n段视频,他要立刻知道第n段视频的编号是多少。


为了尽快看到Wjj拍的视频,你需要写出效率很高的代码来为视频编号,否则就不能欣赏Wjj的作品了。

输入描述 Input Description

输入共一行,一个整数n,表示wjj现在有n段视频

输出描述 Output Description

输出共一行,一个整数,表示第n段视频的编号。

样例输入 Sample Input

【样例输入1】

1


【样例输入2】

4

样例输出 Sample Output

【样例输出1】

1


【样例输出2】

5

数据范围及提示 Data Size & Hint

对于100%的数据,n<10100

和codevs5116题意相同。此题需要用高精度解决。

#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <algorithm>#include <cstring>#define N 5005#define D 10000using namespace std;struct bignum{    int len,x[N];    bignum(int x_=0){x[len=1]=x_;}    bignum(int x_,int y_){for(register int i=1;i<x_;++i)x[i]=0 ;x[len=x_]=y_;}    bignum(char *s);}; bignum::bignum(char *s){    int len_s=strlen(s),cnt=0;    for(int i=len_s-1;i>=0;i-=4)    {        int num=0;        for(register int j=i-3>=0?i-3:0;j<=i;++j) num=num*10+s[j]-'0';        x[++cnt]=num;    }    len=cnt;} inline bool operator < (const bignum &a,const bignum &b){    if(a.len!=b.len) return a.len<b.len;    for(register  int i=a.len;i;--i)        if(a.x[i]!=b.x[i]) return a.x[i]<b.x[i];    return 0;} inline bignum operator + (bignum a,bignum b){bignum c;c.len=max(a.len,b.len);for(int i=c.len+1;i;--i) c.x[i]=0;for(int i=a.len+1;i<=c.len;++i) a.x[i]=0;for(int i=b.len+1;i<=c.len;++i) b.x[i]=0;for(int i=1;i<=c.len;++i)if((c.x[i]+=a.x[i]+b.x[i])>=D) c.x[i]-=D,c.x[i+1]++;if(c.x[c.len+1]) c.len++;return c;}inline bignum operator - (bignum &a,bignum &b){bignum c;c.len=a.len;for(int i=c.len;i;--i) c.x[i]=0;for(int i=b.len+1;i<=c.len;++i) b.x[i]=0;for(int i=1;i<=c.len;++i)if((c.x[i]+=a.x[i]-b.x[i])<0) c.x[i]+=D,c.x[i+1]--;if(a.len>1&&!a.x[a.len]) a.len--;return c;}inline bignum operator * (const bignum &a,const bignum &b){    bignum c;    for(register  int i=a.len+b.len;i;--i) c.x[i]=0;    for( int i=a.len;i;--i)        for(register  int j=b.len;j;--j)        {            c.x[i+j-1]+=a.x[i]*b.x[j];            if(c.x[i+j-1]>=1000000000) c.x[i+j]+=c.x[i+j-1]/D,c.x[i+j-1]%=D;        }    for(register  int i=1,t=a.len+b.len;i<t;++i)        if(c.x[i]>=D) c.x[i+1]+=c.x[i]/D,c.x[i]%=D;    if(!c.x[c.len=a.len+b.len]) c.len--;    return c;}inline void sub(bignum &a){a.x[1]--;for( int j=1;a.x[j]<0;++j)a.x[j+1]--,a.x[j]+=D;if(a.len>1&&!a.x[a.len]) a.len--;}inline bignum sub_r(bignum a){a.x[1]--;for( int j=1;a.x[j]<0;++j)a.x[j+1]--,a.x[j]+=D;if(a.len>1&&!a.x[a.len]) a.len--;return a;}inline bignum add(bignum a){a.x[1]++,a.x[a.len+1]=0;for( int j=1;a.x[j]>=D;++j)a.x[j+1]++,a.x[j]-=D;if(a.x[a.len+1]) a.len++;return a;}inline bignum div2(bignum a){for( int j=a.len;j;--j){if(a.x[j]&1) a.x[j-1]+=D;a.x[j]>>=1;}if(a.len>1&&!a.x[a.len]) a.len--;return a;}void output(const bignum &a){    printf("%d",a.x[a.len]);    for(register int i=a.len-1;i;--i) printf("%04d",a.x[i]);}int main(){freopen("oddeven.in","r",stdin);freopen("oddeven.out","w",stdout);char s[N];scanf("%s",s);bignum n(s),i(n);if(n.len==1&&n.x[1]==1) return puts("1"),0;sub(n);bignum l(0),r(n);while(l<sub_r(r)){bignum mid=div2(l+r);bignum t=div2(mid*add(mid));if(n<t) r=mid;else l=mid;}output((n-l)+i);    return 0;}



0 0
原创粉丝点击