高精专题——一入高精深似海,从此AC是路人.

Posted AWordThatWeDefine

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了高精专题——一入高精深似海,从此AC是路人.相关的知识,希望对你有一定的参考价值。

1.高精简单操作

 

题面

#include<algorithm>
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
struct bigint{
    static const int base=1e+8;
    static const int width=8;
    int s[10001],tot;
    bigint(long long num=0){*this=num;}
    void lenth(){while(tot>0&&!s[tot-1]) --tot;}
    bigint operator = (long long num){//
        tot=0;
        while(num){
            s[tot++]=num%base;
            num/=base;
        }
        this->lenth();
        return *this;
    }
    bigint operator = (char* buf){//
        tot=0;
        int len=strlen(buf),x=0;
        for(register int i=len-1;i>=0;i-=width){
            x=0;
            for(register int j=max(i-width+1,0);j<=i;++j) x=x*10+buf[j]-\'0\';
            s[tot++]=x;
        }
        this->lenth();
        return *this;
    }
    int& operator [] (int x){//
        return s[x];
    }
    void print(){//
        lenth();
        if(!tot){
            putchar(\'0\');
            return;
        }
        int p=tot-1;
        printf("%d",s[p]);
        for(p=tot-2;p>=0;--p) printf("%08d",s[p]);
    }
    bigint operator + (bigint b){//
        bigint c=0;
        int x=0;
        for(register int i=0;i<tot||i<b.tot;++i){
            if(i<tot) x+=s[i];
            if(i<b.tot) x+=b[i];
            c[c.tot++]=x%base;
            x/=base;
        }
        while(x){
            c[c.tot++]=x%base;
            x/=base;
        }
        c.lenth();
        return c;
    }
    friend bool operator < (bigint a,bigint b){//
        if(a.tot!=b.tot) return a.tot<b.tot;
        for(register int i=a.tot-1;i>=0;--i){
            if(a[i]!=b[i]) return a[i]<b[i];
        }
        return false;
    }
    friend bool operator == (bigint a,bigint b){//
        a.lenth();
        b.lenth();
        return (!(a<b)&&!(b<a));
    }
    bool pd(){//
        return !(s[0]&1);
    }
    bigint operator - (bigint b){//
        bigint c=0;
        int x=0,g=0;
        for(register int i=0;i<tot||i<b.tot||g<0;++i){//////////////////////////////////////////
            x=g;
            g=0;
            if(i<tot) x+=s[i];
            if(i<b.tot) x-=b[i];
            while(x<0){
                x+=base;
                --g;
            }
            c[c.tot++]=x%base;
            g+=x/base;
        }
        c.lenth();
        return c;
    }
    bigint divide(){//
        bigint c=0;
        long long int x=0;
        c.tot=tot;
        for(register int i=tot-1;i>=0;--i){
            c[i]=(x*base+s[i])>>1;
            x=(s[i]&1);			
        }
        c.lenth();/////////////////////////////
        return c;
    }
    bigint multi(){//
        long long x=0;
        bigint c=0;
        for(register int i=0;i<tot;++i){
            x+=(s[i]<<1);
            c[c.tot++]=x%base;
            x/=base;
        }
        while(x){
            c[c.tot++]=x%base;
            x/=base;
        }
        return c;
    }
    bigint operator << (int x){//
        bigint c=(*this);
        while(x--) c=c.multi();
        c.lenth();
        return c;
    }
};
const bigint cmp=0;
bigint gcd(bigint a,bigint b){
    int mul=0;
    bigint c;
    while(1){
        if(b==cmp) return mul==0?(a):(a<<mul);
        while((a.pd())&&(b.pd())){
            a=a.divide();
            b=b.divide();
            ++mul;
        }
        while(a.pd()) a=a.divide();
        while(b.pd()) b=b.divide();
        if(a<b) swap(a,b);
        c=a-b;
        if(c<b){
            a=b;
            b=c;
        }
        else a=c;
    }
}
int main(){
    char st[10010];
    bigint a,b,c;
    scanf("%s",st);
    a=st;
    scanf("%s",st);
    b=st;
    if(a<b) swap(a,b);
    c=gcd(a,b);
    c.print();
    return 0;
}

 

高精,GCD,stein.

    gcd(a,b)=2*gcd(a/2,b/2);

    gcd(a,b)=gcd(a/2,b);

    gcd(a,b)=gcd(a,b/2);

    再用辗转相减套个高精就好

 

2.高精除int

 

题面

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int num[10001],l1=0;
int res[10001],len=0;
struct bigint{
    static const int base=10;
    static const int width=1;
    int tot;
    int s[10001];
    bigint(long long num=0){(*this)=num;}
    void lenth(){while(tot>0&&!s[tot-1]) --tot;}
    int& operator [] (int n){
        return s[n];
    }
    bigint operator = (long long num){
        tot=0;
        while(num){
            s[tot++]=num%base;
            num/=base;
        }
        this->lenth();
        return *this;
    }
    bigint operator = (char* buf){
        tot=0;
        int len=strlen(buf);
        for(register int i=len-1;i>=0;--i){
            s[tot++]=buf[i]-\'0\';
        }
        this->lenth();
        return *this;
    }
    bigint mul(int n){
        long long x=0;
        bigint c=0;
        for(register int i=0;i<tot;++i){
            x+=s[i]*n;
            c[c.tot++]=x%base;
            x/=base;
        }
        while(x){
            c[c.tot++]=x%base;
            x/=base;
        }
        return c;
    }
    void print(){
        lenth();
        if(!tot){
            putchar(\'0\');
            return;
        }
        int p=tot-1;
        printf("%d",s[p]);
        for(p=tot-2;p>=0;--p) printf("%d",s[p]);
        return;
    }
    bigint div(int n){
        if(n==1) return *this;
        bigint c;
        long long x=0;
        /*for(register int i=tot-1;i>=0;--i){
            if((s[i]+(x<<1)+(x<<3))>=n){
                x=(x<<1)+(x<<3)+s[i];
                c[i]=x/n;
                c.tot++;
                x%=n;
            }
            else{
                x=(x<<1)+(x<<3)+s[i];
            }
        }*/
        for(register int i=tot-1;i>=0;--i){
            x=(x<<1)+(x<<3)+s[i];
            c[i]=x/n;
            x%=n;
        }
        c.tot=tot;
        c.lenth();
        return c;
    }
};
bigint katalan(int n){
    bigint c=1;
    int N=(n<<1);
    for(register int i=n+2;i<=N;++i)
        c=c.mul(i);
    for(register int i=1;i<=n;++i)
        c=(c.div(i));
    return c;
}
int main(){
    int n;
    bigint a;
    scanf("%d",&n);
    a=katalan(n);
    a.print();
    return 0;
}

 

 

高精,katalan,组合数学.

    暴力打表观察分析一下,易得答案为katalan数

    递推显然是要T的,化简一波就好了

    再套个高精,支持除非高精就行

 

 

3.高精乘高精

 

题面

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
struct bigint{
    static const int base=10;
    static const int width=1;
    int tot,s[10005];
    bigint(long long num=0){*this=num;memset(s,0,sizeof(s));tot=0;}/////////////memset????? 
    void lenth(){while(tot>0&&!s[tot-1])--tot;}
    bigint operator = (long long num){
        tot=0;
        while(num){
            s[tot++]=num%base;
            num/=base;
        }
        this->lenth();
        return *this;
    }
    /*bigint operator = (char* buf){
        tot=0;
        int len=strlen(buf),x=0;
        for(register int i=len-1;i>=0;i-=width){
            x=0;
            for(register int j=max(i-width+1,0);j<=i;++j) x=(x<<1)+(x<<3)+(buf[j]^48);
            s[tot++]=x;
        }
        this->lenth();
        return *this;
    } */
    bigint operator = (string buf){
        tot=0;
        int len=buf.length(),x=0;
        for(register int i=len-1;i>=0;i--){
            x=0;
            for(register int j=max(i-width+1,0);j<=i;++j) x=(x<<1)+(x<<3)+(buf[j]^48);
            s[tot++]=x;
        }
        this->lenth();
        return *this;
    } 
    int& operator [] (int x){
        return s[x];
    }
    friend bool operator < (bigint a,bigint b){
        if(a.tot!=b.tot) return a.tot<b.tot;
        for(register int i=a.tot-1;i>=0;--i){
            if(a[i]!=b[i]) return a[i]<b[i];
        }
        return false;
    }
    void print(){
        lenth();
        if(!tot){
            putchar(\'0\');
            return;
        }
        for(int p=tot-1;p>=0;--p) printf("%d",s[p]);
        return;
    }
    void carry_up(){
        int rep=tot-1;
        for(register int i=0;i<rep;++i){
            if(s[i]>=base){
                s[i+1]+=s[i]/base;
                s[i]%=base;
            }
        }
        int estbit=tot-1,res=s[tot-1]/base;
        while(res){
            ++estbit;
            res/=base;
        }
        //printf("the highest bit of the array is %d\\n",estbit);//DEBUG
        for(register int i=tot-1;i<=estbit;++i){
            if(s[i]>=base){
                s[i+1]=s[i]/base;
                s[i]%=base;
            }
        }
        tot+=estbit+1;
        this->lenth();
        return;
    }
    bigint multiply(bigint b){
        bigint c=0;
        c.tot=0;
        if(tot>b.tot){
            //printf("a.tot>b.tot\\n"); //	DEBUG
            for(register int i=0;i<b.tot;i++){
                for(register int j=0;j<tot;j++){
                    //c[i]=s[i]*b[i];
                    c[i+j]+=b[i]*s[j];
                }
            }
        }
        else{
            //printf("a.tot<=b.tot\\n"); //DEBUG
            for(register int i=0;i<tot;i++){
                for(register int j=0;j<b.tot;j++){
                    //c[i]=s[i]*b[i];
                    c[i+j]+=s[i]*b[j];
                }
            }
        }
        c.tot=tot+b.tot;
        c.lenth();
        //printf("c.tot=%d\\n",c.tot);//DEBUG
        c.carry_up();
        return c;
    }
};
bigint num[41][41],f[41][8];
int n,k;
char str[42];
void getnums(){
    
    string s;//cout<<n<<endl;
    for(register int i=1;i<=n;++i){
        s.clear();
        int j=i;
        for( ;j<=n;++j){
            s=s+str[j-1];
            //cout<<s<<endl;//DEBUG
            num[i][j]=s;
        }
        num[i][j].tot=s.length();
    }
    return;
}
inline bigint max_bigint(bigint a,bigint b){
    if(a<b) return b;
    return a;
}
int main(){
    scanf("%d%d",&n,&k);
    scanf("%s",str);
    /*for(register int i=1;i<=n;++i){
        for(register int j=i;j<=n;++j){
            for(register int l=i;l<=j;++l){
                num[i][j]=num[i][j]*10+(ar[l-1]^48);
            }
        }
    }*/
    getnums();
    /*for(register int i=1;i<=n;++i){//DEBUG
        for(register int j=i;j<=n;++j){
            num[i][j].print();
            putchar(\' \');
        }
        putchar(\'\\n\');
    }*/
    for(register int i=1;i<=n;++i){
        f[i][0]=num[1][i];
    }
    for(register int i=1;i<=n;++i){
        for(register int j=1;j<=k;++j){
            for(register int l=j;l<=i;++l){
                /*f[l][j-1].print();
                printf("(f[%d][%d]) ",l,j-1);
                putchar(\'*\');
                num[l+1][i].print();
                printf("(num[%d][%d]) ",l+1,i);
                putchar(\'=\');
                
                bigint mid;
                mid=(f[l][j-1]).multiply(num[l+1][i]);
                
                mid.print();
                printf("(tot=%d) ",mid.tot);
                putchar(\'\\n\');
                //DEBUG
                printf("f[%d][%d]=max(",i,j);//DEBUG
                f[i][j].print();
                putchar(\',\');
                mid.print();
                putchar(\')\');
                
                f[i][j]=max_bigint(f[i][j],mid);
                
                putchar(\'=\');
                f[i][j].print();
                putchar(\'\\n\');
                putchar(\'\\n\');*/
                f[i][j]=max_bigint(f[i][j],f[l][j-1].multiply(num[l+1][i]));
            }
        }
    }
    /*for(register int i=1;i<=n;++i){//DEBUG
        for(register int j=i;j<=n;++j){
            printf("%lld ",num[i][j]);
        }
        putchar(\'\\n\');
    }*/
    f[n][k].print();
    return 0;
}

 

高精,DP.

    DP不难,高精乘高精倒是DEBUG了一晚上...

 

4.高精大全

 

题面

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
struct bigint{
    static const int base=1e+8;
    static const int width=8;
    int tot;
    long long s[10005];
    bigint(long long num=0){*this=num;memset(s,0,10005);tot=0;}
    void lenth(){while(tot>0&&!s[tot-1]) --tot;}
    bigint operator = (long long num){
        tot=0;
        while(num){
            s[tot++]=num%base;
            num/=base;
        }
        this->lenth();
        return *this;
    }
    bigint operator = (char* buf){
        tot=0;
        int len=strlen(buf),x=0;
        for(int i=len-1;i>=0;i-=width){
            x=0;
            for(int j=max(i-width+1,0);j<=i;++j)
                x=x*10+buf[j]-48;
            s[tot++]=x;
        }
        this->lenth();
        return *this;
    }
    long long int& operator [](int x){
        return s[x];
    }
    void print(){
        lenth();
        if(!tot){
            putchar(\'0\');
            return;
        }
        int p=tot-1;
        printf("%lld",s[p]);
        for(p=tot-2;p>=0;p--)
            printf("%08lld",s[p]);
        return;
    }
    friend bool operator < (bigint a,bigint b){
        if(a.tot!=b.tot) return a.tot<b.tot;
        for(int i=a.tot-1;i>=0;--i)
            if(a[i]!=b[i]) return a[i]<b[i];
        return false;
    }
    friend bool operator == (bigint a,bigint b){
        a.lenth();
        b.lenth();
        return ((!(a<b))&&(!(b<a)));
    }
    friend bool operator <=(bigint a,bigint b){
        return ((a<b)||(a==b));
    }
    bigint operator + (bigint b){
        bigint c=0;
        int x=0;
        for(int i=0;i<tot||i<b.tot;++i){
            (i<tot)?(x+=s[i]):1;
            (i<b.tot)?(x+=b[i]):1;
            c[c.tot++]=x%base;
            x/=base;
        }
        while(x){
            c[c.tot++]=x%base;
            x/=base;
        }
        c.lenth();
        return c;
    }
    bigint operator - (bigint b){
        bigint c=0;
        int x=0,g=0;
        for(int i=0;i<tot||i<b.tot||g<0;++i){
            x=g;
            g=0;
            (i<tot)?(x+=s[i]):1;
            (x<b.tot)?(x-=b[i]):1;
            while(x<0){
                x+=base;
                --g;
            }
            c[c.tot++]=x%base;
            x/=base;
        }
        c.lenth();
        return c;
    }
    void carry_up(){
        int rep=tot-1;
        for(int i=0;i<rep;i++){
            (s[i]>=base)?(s[i+1]+=s[i]/base,s[i]%=base):1;
        }
        int estbit=rep,res=s[rep]/base;
        while(res){
            ++estbit;
            res/=base;
        }
        for(int i=tot-1;i<=estbit;i++){
            (s[i]>=base)?(s[i+1]+=s[i]/base,s[i]%=base):1;
        }
        tot+=estbit+1;
        this->lenth();
        return;
    }
    bigint multiply(bigint b){
        bigint c=0;
        c.tot=0;
        if(tot>b.tot){
            for(int i=0;i<b.tot;i++){
                for(int j=0;j<tot;j++){
                    c[i+j]+=b[i]*s[j];
                }
            }
        }
        else{
            for(int i=0;i<tot;i++){
                for(int j=0;j<b.tot;j++){
                    c[i+j]+=s[i]*b[j];
                }
            }
        }
        c.tot=tot+b.tot;
        c.lenth();
        c.carry_up();
        return c;
    }
    bigint divide(){//
        bigint c=0;
        long long int x=0;
        c.tot=tot;
        for(register int i=tot-1;i>=0;--i){
            c[i]=(x*base+s[i])>>1;
            x=(s[i]&1);			
        }
        c.lenth();/////////////////////////////
        return c;
    }
    bigint multi2(){//
        long long x=0;
        bigint c=0;
        for(register int i=0;i<tot;++i){
            x+=(s[i]<<1);
            c[c.tot++]=x%base;
            x/=base;
        }
        while(x){
            c[c.tot++]=x%base;
            x/=base;
        }
        return c;
    }
};
bigint fmi(bigint a,int x){
    bigint ans;
    ans=1;
    while(x){
        (x&1)?(ans=ans.multiply(a)):1;
        x>>=1;
        a=a.multiply(a);
    }
    return ans;
}
int m;
char a[10005];
int main(){
//	freopen("GG.out","r",stdin);
//	freopen("GGout.out","w",stdout);
    scanf("%d",&m);
    scanf("%s",a);
    bigint GG,r,l,mid,one,ans;
    one=1;
    GG=a;
    r=2;
    l=1;
    
    if(m==1){
        GG.print();
        return 0;
    }
    if(GG<one){
        putchar(\'0\');
        return 0;
    }
    while(1){
        if(fmi(r,m)<GG){
            l=r;
            r=r.multi2();
        }
        else break;
    }
    while(l<r){
        mid=(l+r).divide();
        if(fmi(mid,m)<=GG){
            ans=mid;
            l=mid+one;
        }
        else r=mid-one;
    }
    long long zzzzz=0;
    bigint zzzzzz;
    zzzzzz=zzzzz;
    if(ans==zzzzzz){
        printf("1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
        return 0;
    }
    ans.print();
//	fclose(stdin);
//	fclose(stdout);
    return 0;
}

  

 

高精,二分答案,快速幂.

    极其恶(nao)心(can)的是,n>=0,这要是考试可就真GG了.

    最后一个点莫名其妙WA了就搞了一大大大波特判

以上是关于高精专题——一入高精深似海,从此AC是路人.的主要内容,如果未能解决你的问题,请参考以下文章

#一入python深似海,从此妹纸是路人

二叉树:一入递归深似海,从此offer是路人

一入python情似海,从此妹纸是路人

一入python深似海,从此妹纸是路人

一入pythn深似海,从此妹纸是路人

一入python情似海,从此妹纸是路人