高精专题——一入高精深似海,从此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是路人.的主要内容,如果未能解决你的问题,请参考以下文章