首页 > 编程语言 > 详细

【模板整合计划】基本算法 常用模板—高精度

时间:2019-05-27 17:41:36      阅读:89      评论:0      收藏:0      [点我收藏+]

【模板整合计划】基本算法 常用模板


【快读,快输 】

快读乃考试必备佳品,能大大优化程序运行时间。

#include<cctype>
#include<cstdio>
inline int in(){
    int f=0,x=0;char c=getchar();
    while(c<'0'||c>'9')f|=c=='-',c=getchar();
    while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();
    return f?-x:x;
}
inline int in_(){
    int f=0,x=0;char c=getchar();
    while(!isdigit(c))f|=c=='-',c=getchar();
    while(isdigit(c))x=(x<<1)+(x<<3)+(c^48),c=getchar();
    return f?-x:x;
}
inline void out(int x){
     if(x<0)putchar('-'),x=-x;
     if(x>9)out(x/10);
     putchar(x%10+'0');
}
inline double double_in(){
    double X=0,Y=1.0;
    int f=0;char c=getchar();
    while(c<'0'||c>'9'){f|=c=='-';c=getchar();} 
    while(c>='0'&&c<='9')X=X*10+(c^48),c=getchar(); 
    c=getchar();
    while(c>='0'&&c<='9')X+=(Y/=10)*(c^48),c=getchar(); 
    return f?-X:X;
}
int main(){
    int a=in();out(a);
    double b=double_in();printf("%lf\n",b);
}

【快速幂,龟速乘】

快速幂 \(||\) 取余运算 \([P1226]\)

这个有两种写法:二分,按进制分。按进制分要快些,二分数据范围要小些。

在快速幂的代码中需要做乘法,很有可能会乘爆,所以就需要用龟速乘来缩小数据范围,如果数据范围允许的话,就不用龟速乘,这样可以快些。

#include<cstdio>
#define LL long long
int a,b,mod;
inline int cf(int a,int k){//二分 龟速乘
    if(!k)return 0;
    int x=1,y=cf(a,k>>1);
    x=(LL)y+y%mod;
    if(k&1)x=(LL)x+a%mod;
    return x%mod;
}
inline int slow_cf(int a,int b){//按进制分 龟速乘 
    int x=0;
    while(b){
        if(b&1)x=(x+a)%mod;
        a=a*2%mod;b>>=1;
    }
    return x%mod;
}
inline int mi(int a,int k){//二分 快速幂 
    if(!k)return 1%mod;
    int x=1,y=mi(a,k>>1);
    x=(LL)y*y%mod;
    if(k&1)x=(LL)x*a%mod;
//  x=cf(y,y)%mod;
//  if(k&1)x=cf(x,a)%mod;
    return x%mod;
}
int quick_pow(int x,int k){//按进制分 快速幂 
    int s=1;
    while(k){
        if(k&1)s=(LL)s*x%mod;
        x=(LL)x*x%mod;k>>=1;
//      if(k&1)s=slow_cf(s,x)%mod;
//      x=slow_cf(x,x)%mod;k>>=1;
    }
    return s%mod;
}
int main(){
    scanf("%d%d%d",&a,&b,&mod);
    printf("%d^%d mod %d=%d\n",a,b,mod,quick_pow(a,b));
}

【ST表求区间最值 (RMQ)】

求m区间内的最小值 \([P1440]\)

#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
const int N=1e5+3,inf=2147483647;
int i,j,n,k,m,a[N],lg[N],f1[N][18],f2[N][18];
int main(){
    scanf("%d%d",&n,&k);
    for(i=0;i<=17;i++)
        for(j=0;j<=n+1;j++)
            f1[i][j]=-inf,f2[i][j]=inf;
    lg[1]=0;for(i=2;i<=n;i++)lg[i]=lg[i>>1]+1;m=lg[n];
    for(i=1;i<=n;f2[i][0]=f1[i][0],i++)scanf("%d",&f1[i][0]);
    for(i=1;i<=m;i++)
        for(j=1;j+(1<<i)-1<=n;j++)
            f1[j][i]=max(f1[j][i-1],f1[j+(1<<i-1)][i-1]),f2[j][i]=min(f2[j][i-1],f2[j+(1<<i-1)][i-1]);
    m=lg[k];
    for(i=1;i+k-1<=n;i++)printf("%d %d\n",max(f1[i][m],f1[i+k-(1<<m)][m]),min(f2[i][m],f2[i+k-(1<<m)][m]));
}

【归并排序】

快速排序 \([P1177]\)

#pragma GCC optimize(3,"Ofast","inline")
#pragma GCC optimize(2)
#include<cstdio>
#define Re register int
const int N=5e5+3;
int fu,n,s[N],b[N];long long gs;char ch;
inline void in(int &x){
    fu=x=0;ch=getchar();
    while(ch<'0'||ch>'9')fu|=ch=='-',ch=getchar();
    while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    x=fu?-x:x;
}
void merge(Re L,Re mid,Re R){
    Re i=L,j=mid+1,w=L;
    while(i<=mid&&j<=R){
        if(s[i]<=s[j])b[w++]=s[i++];
        else b[w++]=s[j++],gs+=mid-i+1;
    }
    for(;i<=mid;i++)b[w++]=s[i];
    for(;j<=R;j++)b[w++]=s[j];
    for(i=L;i<=R;i++)s[i]=b[i];
}
inline void Sort(Re L,Re R){
    if(L<R){
        Re mid=L+R>>1;
        Sort(L,mid),Sort(mid+1,R);
        merge(L,mid,R);
    }
}
int main(){
    in(n);
    for(Re i=1;i<=n;i++)in(s[i]);
    Sort(1,n);
    for(Re i=1;i<=n;i++)printf("%d ",s[i]); 
//    printf("%lld",gs);//输出逆序对个数 
}

【快排】

快速排序 \([P1177]\)

排序直接用 \(sort\),求逆序对用归并,快排似乎没啥用哎╮(╯▽╰)╭。

#include<bits/stdc++.h>
using namespace std;
int data[100100],n;
void mysort(int left, int right){
    int mid=data[(left+right)/2];
    int i=left,j=right;
    while(i<=j){
        while(data[i]<mid)i++;
        while(data[j]>mid)j--;
        if(i<=j)swap(data[i++],data[j--]);
    }
    if(j>left)mysort(left,j);
    if(i<right)mysort(i,right);
}
int main(){ 
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&data[i]);
    mysort(1,n);
    for(int i=1;i<=n;i++)printf("%d ",data[i]);
} 

【n 进制转 m 进制】

进制转换 \([P1143]\)

这个感觉很少用到哎。。

#include<cstdio>
const int N=1e5+3;
int n,m,x,tmp,ansl;char a[N],ans[N];
inline int n_to_ten(){
    int x=0;
    for(int i=0;a[i];++i){
        x*=n;
        if (a[i]>='A'&&a[i]<='F')x+=(a[i]-'A'+10);
        else x+=(a[i]-'0');
   }
   return x;
}
inline void ten_to_m(){
    do{
        tmp=x%m;
        if(tmp<10)ans[++ansl]='0'+tmp;
        else ans[++ansl]='A'+tmp-10;
        x/=m;
    }while(x);
}
int main(){
   scanf("%d%s%d",&n,a,&m);
   x=n_to_ten();
   ten_to_m();
   for(int i=ansl;i;--i)printf("%c",ans[i]);puts("");
}

【高精度加法(普通写法)】

\(A+B\) \(Problem\)(高精)\([P1601]\)

#include<bits/stdc++.h>
using namespace std;
int a[1000],b[1000],c[1000];
char st[1000];
int main(){
    scanf("%s",st);
    int lena,lenb,lenc;
    lena =strlen(st);
    for(int i=1;i<=lena;i++)a[i]=st[lena-i]-'0';
    scanf("%s",st);
    lenb=strlen(st);
    for(int i=1;i<=lenb;i++)b[i]=st[lenb-i]-'0';
    if(lena>lenb)lenc=lena;
    else lenc=lenb;
    for(int i=1;i<=lenc;i++){
        c[i]=a[i]+b[i]+c[i];
        c[i+1]=c[i+1]+c[i]/10;
        c[i]=c[i]%10;
    }
    if(c[lenc+1])lenc++;
    for(int i=lenc;i>0;i--)printf("%d",c[i]);
}

【高精度乘法(普通写法)】

\(A*B\) \(Problem\)(高精)\([P1303]\)

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int main(){
    char a1[10005],b1[10005];
    int a[100005],b[100005],c[100005],lena,lenb,lenc,i,j,x;
    memset(a,0,sizeof(a));
    memset(b,0,sizeof(b));
    memset(c,0,sizeof(c));
    gets(a1);gets(b1);
    lena=strlen(a1);lenb=strlen(b1);
    for(i=0;i<=lena-1;i++) a[lena-i]=a1[i]-48;
    for(i=0;i<=lenb-1;i++) b[lenb-i]=b1[i]-48;
    for(i=1;i<=lena;i++){
        x=0;                                               
        for(j=1;j<=lenb;j++){
            c[i+j-1]=a[i]*b[j]+x+c[i+j-1];
            x=c[i+j-1]/10;
            c[i+j-1] %= 10;
        }
        c[i+lenb]=x;                             
    }
    lenc=lena+lenb;
    while(c[lenc]==0&&lenc>1)lenc--;
    for(i=lenc;i>=1;i--)cout<<c[i];
    cout<<endl;
}

【高精全模板(史上最全没有之一)】

\(A\) \(+B\) \(Problem\)(高精)\([P1601]\)

\(A\) \(*\) \(B\) \(Problem\)(高精)\([P1303]\)

\(A\) \(/\) \(B\) \(Problem\)(高精)\([P1480]\)

(强推这个大佬写的高精全模板

代码量略大,疯狂压了波行,还是有两百多行。

如果嫌代码太长,可以吧一些不必要的删掉,只是要注意像除法,取模这样的运算需要用到减法,加法,所以像只留除,模,删掉加,减这样的行为会让你编译不过的。

#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const int base = 1e8;
const int N = 1e4 + 10;
int aux[N << 3];
struct bigint {
    int s[N], l;
    void CL() { l = 0; memset(s, 0, sizeof(s)); }
    void pr(){
        printf("%d", s[l]);
        for (int i = l - 1; i; i--)printf("%08d", s[i]);
    }
    void re_l(){
        int i, x = 0, k = 1, L = 0, fl, o;
        char c = getchar();
        for (; c < '0' || c > '9'; c = getchar());
        for (; c >= '0' && c <= '9'; c = getchar()){
            if (!(L - 1) && !aux[L])L--;
            aux[++L] = c - '0';
        }
        CL();l = L / 8 + ((o = L % 8) > 0);
        for (i = 1; i <= o; i++)x = x * 10 + aux[i];
        if (o)s[l] = x;
        fl = !o ? l + 1 : l;
        for (i = o + 1, x = 0; i <= L; i++, k++){
            x = x * 10 + aux[i];
            if (!(k ^ 8))s[--fl] = x,x = k = 0;
        }
        if (!l)l = 1;
    }
    ll toint(){
        ll x = 0;
        for(int i = l; i; i--)x = x * base + s[i];
        return x;
    }
    bigint operator = (int b){
        CL();
        do s[++l] = b % base,b /= base;while (b > 0);
        return *this;
    }
    bigint operator = (ll b){
        CL();
        do s[++l] = b % base,b /= base;while (b > 0);
        return *this;
    }
    bigint operator + (const int &b){
        bigint c = *this;
        ll x = b;
        for (int i = 1; i <= l && x; i++){
            x = x + c.s[i];
            c.s[i] = x % base;
            x /= base;
        }
        if (x)c.s[++c.l] = x;
        return c;
    }
    bigint operator + (const ll &b){
        bigint c = *this;
        ll x = b;
        for (int i = 1; i <= l && x; i++){
            x = x + c.s[i];
            c.s[i] = x % base;
            x /= base;
        }
        if (x)c.s[++c.l] = x;
        return c;
    }
    bigint operator + (bigint &b){
        if (b.l < 3)return *this + b.toint();
        bigint c;ll x = 0;
        int k = l < b.l ? b.l : l;
        c.CL(),c.l = k;
        for (int i = 1; i <= k; i++){
            x = x + s[i] + b.s[i];
            c.s[i] = x % base;
            x /= base;
        }
        if (x)c.s[++c.l] = x;
        return c;
    }
    bigint operator - (const bigint &b){
        bigint c, d = *this;
        ll x = 0;c.CL();
        for (int i = 1; i <= l; i++){
            if ((x = d.s[i]) < b.s[i])d.s[i + 1]--,x += base;
            c.s[i] = x - b.s[i];
        }
        c.l = l;
        for (; !c.s[c.l] && c.l > 1; c.l--);
        return c;
    }
    bigint operator - (const int &b){bigint c;return *this - (c = b);}
    bigint operator - (const ll &b){bigint c;return *this - (c = b);}
    bigint operator * (const int &b){
        bigint c;ll x = 0;c.CL();
        for (int i = 1; i <= l; i++){
            x = x + 1LL * s[i] * b;
            c.s[i] = x % base;
            x /= base;
        }
        for (c.l = l; x; x /= base)c.s[++c.l] = x % base;
        return c;
    }
    bigint operator * (bigint &b){
        if (b.l < 2)return *this * b.toint();
        bigint c;ll x;int i, j, k;c.CL();
        for (i = 1; i <= l; i++){
            x=0;
            for (j = 1; j <= b.l; j++){
                x = x + 1LL * s[i] * b.s[j] + c.s[k = i + j - 1];
                c.s[k] = x % base;
                x /= base;
            }
            if (x)c.s[i + b.l] = x;
        }
        for (c.l = l + b.l; !c.s[c.l] && c.l > 1; c.l--);
        return c;
    }
    bigint operator * (const ll &b){
        bigint c;
        if (b > 2e9){c = b;return *this * c;}
        ll x = 0;c.CL();
        for (int i = 1; i <= l; i++){
            x = x + b * s[i];
            c.s[i] = x % base;
            x /= base;
        }
        for (c.l = l; x; x /= base)c.s[++c.l] = x % base;
        return c;
    }
    bigint operator / (const int &b){
        bigint c;ll x = 0;c.CL();
        for (int i = l; i; i--){
            c.s[i] = (x * base + s[i]) / b;
            x = (x * base + s[i]) % b;
        }
        for (c.l = l; !c.s[c.l] && c.l > 1; c.l--);
        return c;
    }
    bigint operator / (const ll &b){
        bigint c;ll x = 0;c.CL();
        for (int i = l; i; i--){
            c.s[i] = (x * base + s[i]) / b;
            x = (x * base + s[i]) % b;
        }
        for (c.l = l; !c.s[c.l] && c.l > 1; c.l--);
        return c;
    }
    bigint operator / (bigint &b){
        if (b.l < 2)return *this / b.toint();
        bigint c, d;int i, j, le, r, mid, k;c.CL();d.CL();
        for (i = l; i; i--){
            for (j = ++d.l; j > 1; j--)d.s[j] = d.s[j - 1];
            d.s[1] = s[i];
            if (d < b)continue;
            le = k = 0;r = base - 1;
            while (le <= r){
                mid = (le + r) >> 1;
                if (b * mid <= d)le = mid + 1,k = mid;
                else r = mid - 1;
            }
            c.s[i] = k,d=d-b * k;
        }
        for (c.l = l; !c.s[c.l] && c.l > 1; c.l--);
        return c;
    }
    bigint operator % (const int &b){
        bigint c;ll x = 0;c.CL();
        for (int i = l; i; i--)x = (x * base + s[i]) % b;
        return c = x;
    }
    bigint operator % (const ll &b){
        bigint c;ll x = 0;c.CL();
        for (int i = l; i; i--)x = (x * base + s[i]) % b;
        return c = x;
    }
    bigint operator % (bigint &b){
        if (b.l < 2)return *this % b.toint();
        bigint c;int i, j, le, r, mid, k;c.CL();
        for (i = l; i; i--){
            for (j = ++c.l; j > 1; j--)c.s[j] = c.s[j - 1];
            c.s[1] = s[i];
            if (c < b)continue;
            le = k = 0,r = base - 1;
            while (le <= r){
                mid = (le + r) >> 1;
                if (b * mid <= c)le = mid + 1,k = mid;
                else r = mid - 1;
            }
            c=c-b * k;
        }
        for (; !c.s[c.l] && c.l > 1; c.l--);
        return c;
    }
    bigint operator += (bigint &b){return *this = *this + b;}
    bigint operator += (ll &b){return *this = *this + b;}
    bigint operator += (int &b){return *this = *this + b;}
    bigint operator -= (bigint &b){return *this = *this - b;}
    bigint operator -= (ll &b){return *this = *this - b;}
    bigint operator -= (int &b){return *this = *this - b;}
    bigint operator *= (bigint &b){return *this = *this * b;}
    bigint operator *= (ll &b){return *this = *this * b;}
    bigint operator *= (int &b){return *this = *this * b;}
    bigint operator /= (bigint &b){return *this = *this / b;}
    bigint operator /= (ll &b){return *this = *this / b;}
    bigint operator /= (int &b){return *this = *this / b;}
    bigint operator %= (bigint &b){return *this = *this % b;}
    bigint operator %= (ll &b){return *this = *this % b;}
    bigint operator %= (int &b){return *this = *this % b;}
    bool operator < (const bigint &b) const{
        if (l ^ b.l)return l < b.l;
        for (int i = l; i; i--)if (s[i] ^ b.s[i])return s[i] < b.s[i];
        return false;
    }
    bool operator <= (const bigint &b) const{
        if (l ^ b.l)return l < b.l;
        for (int i = l; i; i--)if (s[i] ^ b.s[i])return s[i] < b.s[i];
        return true;
    }
    bool operator > (const bigint &b) const{
        if (l ^ b.l)return l > b.l;
        for (int i = l; i; i--)
            if (s[i] ^ b.s[i])return s[i] > b.s[i];
        return false;
    }
    bool operator >= (const bigint &b) const{
        if (l ^ b.l)return l > b.l;
        for (int i = l; i; i--)if (s[i] ^ b.s[i])return s[i] > b.s[i];
        return true;
    }
    bool operator == (const bigint &b) const{
        if (l ^ b.l)return false;
        for (int i = l; i; i--)if (s[i] ^ b.s[i])return false;
        return true;
    }
    bool operator != (const bigint &b) const{
        if (l ^ b.l)return true;
        for (int i = l; i; i--)if (s[i] ^ b.s[i])return true;
        return false;
    }
    bool operator < (ll b) const{bigint c;return *this < (c = b);}
    bool operator <= (ll b) const{bigint c;return *this <= (c = b);}
    bool operator > (ll b) const{bigint c;return *this > (c = b);}
    bool operator >= (ll b) const{bigint c;return *this >= (c = b);}
    bool operator == (ll b) const{bigint c;return *this == (c = b);}
    bool operator != (ll b) const{bigint c;return *this != (c = b);}
    bool operator < (int b) const{bigint c;return *this < (c = b);}
    bool operator <= (int b) const{bigint c;return *this <= (c = b);}
    bool operator > (int b) const{bigint c;return *this > (c = b);}
    bool operator >= (int b) const{bigint c;return *this >= (c = b);}
    bool operator == (int b) const{bigint c;return *this == (c = b);}
    bool operator != (int b) const{bigint c;return *this != (c = b);}
};
bigint a,b;
int main(){
    a.re_l();
    b.re_l();
    a.pr();printf("+");b.pr();printf("=");(a + b).pr();printf("\n");
    a.pr();printf("-");b.pr();printf("=");
    if (a < b){putchar('-');(b - a).pr();}
    else (a - b).pr();printf("\n");
    a.pr();printf("*");b.pr();printf("=");(a * b).pr();printf("\n");
    a.pr();printf("/");b.pr();printf("=");(a / b).pr();printf("\n");
    a.pr();printf("%%");b.pr();printf("=");(a % b).pr();printf("\n");
    if (a < b)printf("a<b\n");
    if (a <= b)printf("a<=b\n");
    if (a > b)printf("a>b\n");
    if (a >= b)printf("a>=b\n");
    if (a == b)printf("a==b\n");
    if (a != b)printf("a!=b\n");
    return 0;
}

【模板整合计划】基本算法 常用模板—高精度

原文:https://www.cnblogs.com/Xing-Ling/p/10931144.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!