模板大全

堆优化 dijkstra

int dis[N],vis[N];
struct Node{
    int x,d;
    Node(){}
    Node(int _x,int _d){
        x=_x,d=_d;
    }
    friend bool operator < (Node x,Node y){
        return x.d>y.d;
    }
};
priority_queue <Node> Q;
void Dijkstra(){
    while (!Q.empty())
        Q.pop();
    for (int i=1;i<=n;i++)
        dis[i]=2e9+5;
    dis[1]=0;
    memset(vis,0,sizeof vis);
    Q.push(Node(1,0));
    while (!Q.empty()){
        Node now=Q.top();
        Q.pop();
        int x=now.x;
        if (vis[x])
            continue;
        vis[x]=1,dis[x]=now.d;
        for (int i=g.fst[x];i;i=g.nxt[i])
            Q.push(Node(g.y[i],dis[x]+g.z[i]));
    }
}
View Code

exgcd

int exgcd(int a,int b,int &x,int &y){
    if (!b){
        x=1,y=0;
        return a;
    }
    int res=exgcd(b,a%b,y,x);
    y-=(a/b)*x;
    return q;
}
View Code

exkmp

#include <bits/stdc++.h>
using namespace std;
void exKMP(char s[],char t[],int g[],int f[],int n,int m){
    int Max=0;
    f[0]=m;
    for (int i=1;i<m;i++){
        f[i]=max(0,min(f[i-Max],Max+f[Max]-i));
        while (i+f[i]<m&&t[f[i]]==t[i+f[i]])
            f[i]++;
        if (!Max||i+f[i]>Max+f[Max])
            Max=i;
    }
    Max=0;
    for (int i=0;i<n;i++){
        g[i]=max(0,min(f[i-Max],Max+g[Max]-i));
        while (i+g[i]<n&&t[g[i]]==s[i+g[i]])
            g[i]++;
        if (!Max||i+g[i]>Max+g[Max])
            Max=i;
    }
}
int main(){
    
    return 0;
}
View Code

FFT

#include <bits/stdc++.h>
using namespace std;
const int N=1<<20;
const double PI=acos(-1.0);
struct C{
    double r,i;
    C(){}
    C(double a,double b){r=a,i=b;}
    C operator + (C x){return C(r+x.r,i+x.i);}
    C operator - (C x){return C(r-x.r,i-x.i);}
    C operator * (C x){return C(r*x.r-i*x.i,r*x.i+i*x.r);}
}a[N],b[N],w[N];
int A,B,n,L,R[N];
void FFT(C a[],int n){
    for (int i=0;i<n;i++)
        if (R[i]>i)
            swap(a[R[i]],a[i]);
    for (int t=n>>1,d=1;d<n;d<<=1,t>>=1)
        for (int i=0;i<n;i+=(d<<1))
            for (int j=0;j<d;j++){
                C tmp=w[t*j]*a[i+j+d];
                a[i+j+d]=a[i+j]-tmp;
                a[i+j]=a[i+j]+tmp;
            }
}
int main(){
    scanf("%d",&A);A++;
    scanf("%d",&B);B++;
    for (int i=0;i<A;i++)
        scanf("%lf",&a[i].r);
    for (int i=0;i<B;i++)
        scanf("%lf",&b[i].r);
    for (n=1,L=0;n<=A+B;n<<=1,L++);
    for (int i=0;i<n;i++){
        R[i]=(R[i>>1]>>1)|((i&1)<<(L-1));
        w[i]=C(cos(2.0*i*PI/n),sin(2.0*i*PI/n));
    }
    FFT(a,n),FFT(b,n);
    for (int i=0;i<n;i++)
        a[i]=a[i]*b[i],w[i].i=-w[i].i;
    FFT(a,n);
    A--,B--;
    for (int i=0;i<=A+B;i++)
        printf("%d ",int(a[i].r/n+0.5));
    
    return 0;
}
View Code

NTT

#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <cstring>
using namespace std;
typedef long long LL;
const LL mod=998244353;
const int N=1<<20;
LL Pow(LL x,LL y){
    if (!y)
        return 1LL;
    LL xx=Pow(x,y/2);
    xx=xx*xx%mod;
    if (y&1LL)
        xx=xx*x%mod;
    return xx;
}
LL A,B,a[N],b[N],R[N],g[N],n,L;
char str[N];
void read(){
    scanf("%s",str);
    A=strlen(str);
    for (int i=0;i<A;i++)
        a[A-i-1]=str[i]-'0';
    scanf("%s",str);
    B=strlen(str);
    for (int i=0;i<B;i++)
        b[B-i-1]=str[i]-'0';
}
void NTT(LL a[N],int n){
    for (int i=0;i<n;i++)
        if (i<R[i])
            swap(a[i],a[R[i]]);
    for (int d=1,t=n>>1;d<n;d<<=1,t>>=1)
        for (int i=0;i<n;i+=(d<<1))
            for (int j=0;j<d;j++){
                LL tmp=g[t*j]*a[i+j+d]%mod;
                a[i+j+d]=(a[i+j]-tmp+mod)%mod;
                a[i+j]=(a[i+j]+tmp)%mod;
            }
}
int main(){
    read();
    for (n=1,L=0;n<=A+B;n<<=1,L++);
    for (int i=0;i<n;i++)
        R[i]=(R[i>>1]>>1)|((i&1)<<(L-1));
    g[0]=1,g[1]=Pow(3,(mod-1)/n);
    for (int i=2;i<n;i++)
        g[i]=g[i-1]*g[1]%mod;
    NTT(a,n),NTT(b,n);
    for (int i=0;i<n;i++)
        a[i]=a[i]*b[i]%mod;
    g[0]=1,g[1]=Pow(g[1],mod-2);
    for (int i=2;i<n;i++)
        g[i]=g[i-1]*g[1]%mod;
    NTT(a,n);
    LL Inv=Pow(n,mod-2);
    for (int i=0;i<n;i++)
        a[i]=a[i]*Inv%mod;
    for (int i=0;i<n-1;i++)
        a[i+1]+=a[i]/10,a[i]%=10;
    int d;
    for (d=n-1;d&&!a[d];d--);
    for (int i=d;i>=0;i--)
        putchar(a[i]+'0');
    return 0;
}
View Code

KM

int ex[N],ey[N],minadd[N],match[N];
bool visx[N],visy[N];
bool Match(int x){
    visx[x]=1;
    for (int i=1;i<=n;i++)
        if (!visy[i]){
            int add=ex[x]+ey[i]-g[x][i];
            if (!add){
                visy[i]=1;
                if (!match[i]||Match(match[i])){
                    match[i]=x;
                    return 1;
                }
            }
            else
                minadd[i]=min(minadd[i],add);
        }
    return 0;
}
int KM(){
    memset(match,0,sizeof match);
    memset(ex,0,sizeof ex);
    memset(ey,0,sizeof ey);
    for (int i=1;i<=n;i++)
        for (int j=1;j<=n;j++)
            ex[i]=max(ex[i],g[i][j]);
    for (int i=1;i<=n;i++){
        for (int j=1;j<=n;j++)
            minadd[j]=INF;
        while (1){
            memset(visx,0,sizeof visx);
            memset(visy,0,sizeof visy);
            if (Match(i))
                break;
            int d=INF;
            for (int j=1;j<=n;j++)
                if (!visy[j])
                    d=min(d,minadd[j]);
            for (int j=1;j<=n;j++){
                if (visx[j])
                    ex[j]-=d;
                if (visy[j])
                    ey[j]+=d;
                else
                    minadd[j]-=d;
            }
        }
    }
    int ans=0;
    for (int i=1;i<=n;i++)
        ans+=g[match[i]][i];
    return ans;
}
View Code

Manachar

char s[N],str[N];
void Manachar(){
    for (int i=0;i<n;i++)
        str[i*2+1]=s[i+1];
    for (int i=0;i<=n;i++)
        str[i*2]='%';
    int R=0,p=0;
    for (int i=1;i<n*2;i++){
        r[i]=max(1,min(r[p*2-i],R-i));
        while (i-r[i]>=0&&i+r[i]<=n*2&&str[i-r[i]]==str[i+r[i]])
            r[i]++;
        if (i+r[i]>R)
            R=i+r[i],p=i;
    }
}
View Code

Pollard_Rho (RXDoi)

#include<bits/stdc++.h>
#define pb push_back
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
vector<LL> V;
namespace Rho {
    int prime[9] = {2, 3, 5, 7, 11, 13, 17, 19, 23};
    ULL RR; int Pcnt; LL p[70];
    LL R(LL MOD) { return (RR += 4179340454199820289ll) % MOD; }
    LL mul(LL x, LL y, LL MOD){
        LL tmp = (x * y - (LL)((long double)x / MOD * y + 0.5) * MOD);
        return tmp < 0 ? tmp + MOD : tmp;
    }
    //O(1)快速乘:http://blog.csdn.net/qq_35649707/article/details/76732760
    LL Pow(LL x,LL k,LL MOD){
        LL ans=1;
        for(; k; k>>=1,x=mul(x,x,MOD)) if (k&1) ans = mul(ans, x, MOD);
        return ans;
    }
    int MR(LL n){
        if (n <= 1) return 0;
        for (int i=0; i<9; i++) if (n == prime[i]) return 1;
        LL d = n - 1; int tmp = 0;
        while ((d&1) == 0) d >>= 1, tmp++;
        for(int i=0; i<9; i++){
            LL x = Pow(prime[i], d, n), p = x;
            for(int j=1; j<=tmp; j++){
                x = mul(x,x,n);
                if (x == 1 && p != 1 && p != n-1) return 0;
                p = x;
            }
            if(x != 1)return 0;
        }
        return 1;
    }
    LL f(LL x,LL c,LL MOD){ return (mul(x, x, MOD) + c) % MOD;}
    LL gcd(LL x,LL y) { return !x ? y : gcd(y%x,x); }
    LL check(LL c,LL n){
        LL x = R(n), y = f(x, c, n), p = n;
        while(x != y && (p == n || p == 1)){
            if (x > y) p = gcd(n, x - y);
            else p = gcd(n, y - x);
            x = f(x, c, n);
            y = f(f(y, c, n), c, n);
        }
        return p;
    }
    void rho(LL n){
        if (n <= 1) return;
        if (MR(n)) { V.pb(n); return; }
        while(true){
            LL tmp = check(R(n - 1) + 1, n);
            if (tmp != n && tmp != 1) { rho(tmp), rho(n/tmp); return; }
        }
    }
}
int main() {
    LL n; scanf("%lld", &n); Rho::rho(n);
    printf("%lld\n", V.back());
    return 0;
}
View Code

SA (附带 ST 表查询区间 LCP )

int SA[N],rank[N],tmp[N],height[N],tax[N];
int ST[N][20];
void Sort(int n,int m){
    for (int i=0;i<=m;i++)
        tax[i]=0;
    for (int i=1;i<=n;i++)
        tax[rank[i]]++;
    for (int i=1;i<=m;i++)
        tax[i]+=tax[i-1];
    for (int i=n;i>=1;i--)
        SA[tax[rank[tmp[i]]]--]=tmp[i];
}
bool cmp(int rk[],int x,int y,int w){
    return rk[x]==rk[y]&&rk[x+w]==rk[y+w];
}
void Suffix_Array(int s[],int n){
    memset(SA,0,sizeof SA);
    memset(tmp,0,sizeof tmp);
    memset(rank,0,sizeof rank);
    memset(height,0,sizeof height);
    for (int i=1;i<=n;i++)
        rank[i]=s[i],tmp[i]=i;
    int m=234;
    Sort(n,m);
    for (int w=1,p=0;p<n;w<<=1,m=p){
        p=0;
        for (int i=n-w+1;i<=n;i++)
            tmp[++p]=i;
        for (int i=1;i<=n;i++)
            if (SA[i]>w)
                tmp[++p]=SA[i]-w;
        Sort(n,m);
        swap(rank,tmp);
        rank[SA[1]]=p=1;
        for (int i=2;i<=n;i++)
            rank[SA[i]]=cmp(tmp,SA[i],SA[i-1],w)?p:++p;
    }
    for (int i=1,j,k=0;i<=n;height[rank[i++]]=k)
        for (k=max(k-1,0),j=SA[rank[i]-1];s[i+k]==s[j+k];k++);
    height[1]=0;
}
void Get_ST(int n){
    memset(ST,0,sizeof ST);
    for (int i=1;i<=n;i++){
        ST[i][0]=height[i];
        for (int j=1;j<20;j++){
            ST[i][j]=ST[i][j-1];
            if (i-(1<<(j-1))>0)
                ST[i][j]=min(ST[i][j],ST[i-(1<<(j-1))][j-1]);
        }
    }
}
int Query(int L,int R){
    int val=floor(log(R-L+1)/log(2));
    return min(ST[L+(1<<val)-1][val],ST[R][val]);
}
View Code

SAM (非广义)

#include <bits/stdc++.h>
using namespace std;
struct SAM{
    int Next[26],fa,Max;
}t[N<<1];
int size=1,root=1,last=1;
void extend(int c){
    int p=last,np=++size,q,nq;
    t[np].Max=t[p].Max+1;
    for (;p&&!t[p].Next[c];p=t[p].fa)
        t[p].Next[c]=np;
    if (!p)
        t[np].fa=root;
    else {
        q=t[p].Next[c];
        if (t[q].Max==t[p].Max+1)
            t[np].fa=q;
        else {
            nq=++size;
            t[nq]=t[q],t[nq].Max=t[p].Max+1;
            t[q].fa=t[np].fa=nq;
            for (;p&&t[p].Next[c]==q;p=t[p].fa)
                t[p].Next[c]=nq;
        }
    }
    last=np;
}
View Code

ISAP

#include <cstring>
#include <cstdio>
#include <cstdlib> 
#include <cmath>
#include <algorithm>
using namespace std;
const int N=55005,M=N*3*2,INF=1e9;
struct edge{
    int x,y,cap,flow,nxt;
};
struct gragh{
    int cnt,fst[N],dist[N],n,S,T,num[N],cur[N],p[N];
    int q[N],head,tail;
    edge e[M];
    void set(int _S,int _T,int _n){
        S=_S,T=_T,n=_n,cnt=1;
        memset(fst,0,sizeof fst);
    }
    void add(int a,int b,int c){
        cnt++;
        e[cnt].x=a,e[cnt].y=b,e[cnt].cap=c,e[cnt].flow=0;
        e[cnt].nxt=fst[a],fst[a]=cnt;
        cnt++;
        e[cnt].x=b,e[cnt].y=a,e[cnt].cap=0,e[cnt].flow=0;
        e[cnt].nxt=fst[b],fst[b]=cnt;
    }
    void bfs(){
        memset(dist,-1,sizeof dist);
        head=tail=dist[T]=0;
        q[++tail]=T;
        while (head<tail)
            for (int x=q[++head],y,i=fst[x];i;i=e[i].nxt)
                if ((i&1)&&dist[y=e[i].y]==-1)
                    dist[q[++tail]=y]=dist[x]+1;
        for (int i=1;i<=n;i++)
            if (dist[i]==-1)
                dist[i]=n;
    }
    void init(){
        bfs();
        memset(num,0,sizeof num);
        for (int i=1;i<=n;i++)
            num[dist[i]]++,cur[i]=fst[i];
    }
    int Augment(int &x){
        int ex_flow=INF;
        for (int i=T;i!=S;i=e[p[i]].x)
            if (e[p[i]].cap-e[p[i]].flow<=ex_flow)
                ex_flow=e[p[i]].cap-e[p[i]].flow,x=e[p[i]].x;
        for (int i=T;i!=S;i=e[p[i]].x)
            e[p[i]].flow+=ex_flow,e[p[i]^1].flow-=ex_flow;
        return ex_flow;
    }
    int ISAP(){
        int x=S,y,MaxFlow=0;
        init();
        while (dist[S]<n){
            if (x==T){
                MaxFlow+=Augment(x);
                continue;
            }
            bool found=0;
            for (int i=cur[x];i;i=e[i].nxt)
                if (dist[y=e[i].y]+1==dist[x]&&e[i].cap>e[i].flow){
                    cur[x]=p[y]=i,x=y,found=1;
                    break;
                }
            if (!found){
                int d=n+1;
                for (int i=fst[x];i;i=e[i].nxt)
                    if (e[i].cap>e[i].flow)
                        d=min(d,dist[e[i].y]+1);
                if (!--num[dist[x]])
                    return MaxFlow;
                num[dist[x]=d]++,cur[x]=fst[x],x=x==S?x:e[p[x]].x;
            }
        }
        return MaxFlow;
    }
}g;
View Code

SPFA 费用流

#include <cstring>
#include <cstdio>
#include <cmath> 
#include <cstdlib>
#include <algorithm>
using namespace std;
const int N=85;
struct edge{
    int x,y,flow,cap,nxt,cost;
};
struct gragh{
    static const int N=85*85,M=N*N*2;
    int n,m,S,T,lim,fst[N],f[N],a[N],p[N],q[N],d[N];
    edge e[M];
    void init(int _n,int _lim){
        n=_n,m=1,lim=_lim;
        memset(fst,0,sizeof fst);
    }
    void add(int a,int b,int cap,int cost){
        m++;
        e[m].x=a,e[m].y=b,e[m].cap=cap,e[m].cost=cost,e[m].flow=0;
        e[m].nxt=fst[a],fst[a]=m;
        m++;
        e[m].x=b,e[m].y=a,e[m].cap=0,e[m].cost=-cost,e[m].flow=0;
        e[m].nxt=fst[b],fst[b]=m;
    }
    bool SPFA(int S,int T,int &flow,int &cost){
        int head=0,tail=0,qmod=n+1,x,y;
        memset(f,0,sizeof f);
        for (int i=1;i<=n;i++)
            d[i]=1e9;
        d[S]=0,q[tail=tail%qmod+1]=S,a[S]=1e9;
        while (head!=tail){
            f[x=q[head=head%qmod+1]]=0;
            for (int i=fst[x];i;i=e[i].nxt){
                y=e[i].y;
                if (e[i].flow<e[i].cap&&d[x]+e[i].cost<d[y]){
                    d[y]=d[x]+e[i].cost;
                    a[y]=min(a[x],e[i].cap-e[i].flow);
                    p[y]=i;
                    if (!f[y])
                        f[q[tail=tail%qmod+1]=y]=1;
                }
            }
        }
        if (d[T]>5e8)
            return 0;
        flow+=a[T],cost+=d[T]*a[T];
        for (x=T;x!=S;x=e[p[x]].x)
            e[p[x]].flow+=a[T],e[p[x]^1].flow-=a[T];
        return 1;
    }
    int MinCost(int S,int T){
        int flow=0,cost=0;
        while (SPFA(S,T,flow,cost));
        if (flow<lim)
            return -1;
        return cost;
    }
}g;
View Code

Splay - BZOJ3224

#include <bits/stdc++.h>
using namespace std;
const int N=100005;
int n,root=1,size=1,val[N],cnt[N],son[N][2],fa[N],tot[N];
int wson(int x){
    return son[fa[x]][1]==x;
}
void pushup(int x){
    tot[x]=cnt[x]+tot[son[x][0]]+tot[son[x][1]];
}
void rotate(int x){
    if (!x)
        return;
    int y=fa[x],z=fa[y],L=wson(x),R=L^1;
    if (z)
        son[z][wson(y)]=x;
    fa[x]=z,fa[y]=x,fa[son[x][R]]=y;
    son[y][L]=son[x][R],son[x][R]=y;
    pushup(y),pushup(x);
}
void splay(int x,int k){
    if (!x)
        return;
    if (!k)
        root=x;
    for (int y=fa[x];fa[x]!=k;rotate(x),y=fa[x])
        if (fa[y]!=k)
            rotate(wson(x)==wson(y)?y:x);
}
int find(int x,int v){
    return val[x]==v?x:find(son[x][v>val[x]],v);
}
int findkth(int x,int k){
    if (k<=tot[son[x][0]])
        return findkth(son[x][0],k);
    k-=tot[son[x][0]];
    if (k<=cnt[x])
        return x;
    k-=cnt[x];
    return findkth(son[x][1],k);
}
int findnxt(int x,int v){
    if (!x)
        return 0;
    if (val[x]<=v)
        return findnxt(son[x][1],v);
    else {
        int res=findnxt(son[x][0],v);
        return res?res:x;
    }
}
int findpre(int x,int v){
    if (!x)
        return 0;
    if (val[x]>=v)
        return findpre(son[x][0],v);
    else {
        int res=findpre(son[x][1],v);
        return res?res:x;
    }
}
void insert(int &x,int pre,int v){
    if (!x){
        x=++size;
        val[x]=v,cnt[x]=tot[x]=1,fa[x]=pre;
        splay(x,0);
        return;
    }
    tot[x]++;
    if (val[x]==v){
        cnt[x]++;
        return;
    }
    insert(son[x][v>val[x]],x,v);
}
void Insert(int v){insert(root,0,v);}
void Delete(int v){
    int x;
    splay(x=find(root,v),0);
    if (--cnt[x])
        return;
    splay(findnxt(root,v),root);
    root=son[x][1];
    son[root][0]=son[x][0];
    fa[son[x][0]]=root;
    fa[root]=son[x][0]=son[x][1]=0;
    pushup(root);
}
int Rank(int v){
    splay(find(root,v),0);
    return tot[son[root][0]]+1;
}
int main(){
    val[1]=2147483647;
    cnt[1]=tot[1]=1;
    scanf("%d",&n);
    while (n--){
        int opt,x;
        scanf("%d%d",&opt,&x);
        if (opt==1) Insert(x);
        if (opt==2) Delete(x);
        if (opt==3) printf("%d\n",Rank(x));
        if (opt==4) printf("%d\n",val[findkth(root,x)]);
        if (opt==5) printf("%d\n",val[findpre(root,x)]);
        if (opt==6) printf("%d\n",val[findnxt(root,x)]);
    }
    return 0;
}
View Code

高精度整数运算 (由于懒和菜,没有更新带 FFT 的乘法和快速的除法)

  支持负数

#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
using namespace std;
typedef long long LL;
/* 
大数模板8 
1.  支持大数之间的+、-、*、/、%运算,以及一些基础的计算 
2.  支持部分大数与整型之间的运算 (仅限于大数在前整型在后) +、-、*、/、% 
3.  支持负数的运算,不会出现减法的时候由于被减数小于减数所造成的报错。 
4.  快速幂,代码优化 
5.  可以进行正常的比较。 
6.  新增 abs(), read()两个方便的函数 
                read() 具体用法 
                1. read('c',Var_Name<BigInt>)  读入一个char数组类型转化而来的大数 
                2. read('i',Var_Name<BigInt>)  读入一个int类型转化而来的大数 
                3. read('L',Var_Name<BigInt>)  读入一个long long类型转化而来的大数 
7.  修复原先模板中关于0的bug 
8.  新增构造函数 
9.  修复若干bug,新增一些功能  
10. progress: 9位压位,大大提高效率 
*///版权所有--周镇东 
const int MaxLen=1200;
const LL mod=1e9;
const LL Pow10[9]={1e0,1e1,1e2,1e3,1e4,1e5,1e6,1e7,1e8};
struct BigInt{
    LL d,v[MaxLen+5];
    bool f;//保存正负性 ,0当作正数看待 
    BigInt (){}
    BigInt (LL x){(*this)=x;}
    BigInt (int x){(*this)=x;}
    BigInt (char x[]){(*this)=x;}
    BigInt (const BigInt &x){(*this)=x;}
    void Print(){
        if (f)
            putchar('-');
        if (d==0){
            putchar('0');
            return;
        }
        printf("%lld",v[d]);
        for (int i=d-1;i>=1;i--)
            printf("%09lld",v[i]);
    }
    void Print(char c){//输出数字 
        (*this).Print();
        printf("%c",c);
    }
    void ya(){
        LL v_[MaxLen];
        memset(v_,0,sizeof v_);
        for (int i=1;i<=d;i++)
            v_[(i-1)/9+1]+=Pow10[(i-1)%9]*v[i];
        d=(d-1)/9+1;
        memset(v,0,sizeof v);
        for (int i=1;i<=d;i++)
            v[i]=v_[i];
        while (d>0&&v[d]==0)
            d--;
    }
    void operator =(char x[]){
        f=x[0]=='-',d=strlen(x)-f,memset(v,0,sizeof v);
        for (int i=f;i<d+f;i++)
            v[i-f+1]+=(x[d+f-(i-f)-1]-48);
        while (d>0&&v[d]==0)
            d--;
        (*this).ya();
    }
    void operator =(int x){
        (*this)=(LL)x;
    }
    void operator =(LL x){
        d=0,f=x<0,x=abs(x);
        memset(v,0,sizeof v);
        while (x)
            v[++d]=x%mod,x/=mod;
    }
    bool equ(BigInt &x){//cmp abs
        if (d!=x.d)
            return 0;
        for (int i=1;i<=d;i++)
            if (v[i]!=x.v[i])
                return 0;
        return 1;
    }
    bool operator ==(BigInt &x){//cmp abs
        if (f!=x.f) 
            return 0;
        return (*this).equ(x);
    }
    bool nequ(BigInt &x){
        return !(*this).equ(x);
    }
    bool operator !=(BigInt &x){
        return !(*this==x);
    }
    bool smaller(BigInt &x){
        if (d!=x.d)
            return d<x.d;
        for (int i=d;i>=1;i--)
            if (v[i]!=x.v[i])
                return v[i]<x.v[i];
        return 0;
    }
    bool bigger(BigInt &x){
        if (d!=x.d)    
            return d>x.d;
        for (int i=d;i>=1;i--)
            if (v[i]!=x.v[i])
                return v[i]>x.v[i];
        return 0;
    }
    bool operator <(BigInt &x){//cmp abs
        if (f!=x.f) 
            return f;
        if (f&&x.f) 
            return (*this).bigger(x);
        return (*this).smaller(x);
    }
    bool operator >(BigInt &x){
        if (f!=x.f) 
            return x.f;
        if (f&&x.f) 
            return (*this).smaller(x);
        return (*this).bigger(x);
    }
    bool smqu(BigInt &x){
        return !(*this).bigger(x);
    }
    bool bgqu(BigInt &x){
        return !(*this).smaller(x);
    }
    bool operator <=(BigInt &x){
        return !(*this>x);
    }
    bool operator >=(BigInt &x){
        return !(*this<x);
    }
    BigInt operator +(BigInt x){//加法运算 
        BigInt Ans=*this;
        if (f!=x.f){
            Ans.f=x.f=0;
            if (f)
                return x-Ans;
            else
                return Ans-x;
        }
        memset(Ans.v,0,sizeof Ans.v);
        Ans.f=f,Ans.d=max(d,x.d);
        for (int i=1;i<=Ans.d;i++)
            Ans.v[i]=v[i]+x.v[i];
        for (int i=1;i<=Ans.d;i++)
            Ans.v[i+1]+=Ans.v[i]/mod,Ans.v[i]%=mod;
        if (Ans.v[Ans.d+1])    
            Ans.d++;
        if (Ans.d==0)
            Ans.f=0;
        return Ans;
    }
    BigInt operator +(const LL x){
        BigInt X(x);
        return X+(*this);
    }
    BigInt operator -(BigInt y){//减法运算 
        BigInt Ans=*this;
        if (f!=y.f){
            y.f=Ans.f,Ans=Ans+y;
            return Ans;
        }
        if (Ans.equ(y)){
            Ans=0;
            return Ans;
        }
        if (Ans.smaller(y)){
            Ans=y-Ans,Ans.f=!f;
            return Ans;
        }
        for (int i=1;i<=max(Ans.d,y.d);i++)
            if (Ans.v[i]-y.v[i]<0)
                Ans.v[i]+=mod-y.v[i],Ans.v[i+1]--;
            else
                Ans.v[i]-=y.v[i];
        while (Ans.d>0&&Ans.v[Ans.d]==0)
            Ans.d--;
        if (Ans.d==0) 
            Ans.f=0;
        return Ans;
    }
    BigInt operator -(const LL x){
        BigInt Ans(x);
        return (*this)-Ans;
    }
    BigInt operator *(const BigInt &y){//乘法运算 
        BigInt x=*this,Ans(0);
        Ans=0,Ans.f=f^y.f;
        for (int i=1;i<=x.d;i++)
            for (int j=1;j<=y.d;j++){
                LL now=Ans.v[i+j-1]+x.v[i]*y.v[j];
                Ans.v[i+j-1]=now%mod;
                Ans.v[i+j]+=now/mod;
            }
        Ans.d=x.d+y.d-1;
        for (int i=1;i<=Ans.d;i++)
            Ans.v[i+1]+=Ans.v[i]/mod,Ans.v[i]%=mod;
        if (Ans.v[Ans.d+1])    
            Ans.d++;
        if (Ans.d==0)
            Ans.f=0;
        return Ans;
    }
    BigInt operator *(LL y){
        BigInt Ans=*this;
        if (y<0) 
            Ans.f^=1;
        y=abs(y);
        for (int i=1;i<=d;i++)
            Ans.v[i]*=y;
        for (int i=1;i<=d||Ans.v[i]>0;i++)
            Ans.v[i+1]+=Ans.v[i]/mod,Ans.v[i]%=mod,Ans.d=max(d,i);
        if (Ans.d==0) 
            Ans.f=0;
        return Ans;
    }
    BigInt operator /(BigInt y){//除法运算 
        BigInt Ans(0),x=*this,minus;
        bool Ansf=f^y.f;
        x.f=y.f=0,minus=y;
        while ((minus*10).smqu(x))
            minus=minus*10;
        while (minus.bgqu(y)){
            Ans=Ans*10;
            while (minus.smqu(x))
                x=x-minus,Ans=Ans+1;
            minus=minus/10;
        }
        Ans.f=Ansf;
        if (Ans.d==0) 
            Ans.f=0;
        return Ans;
    }
    BigInt operator /(LL x){
        BigInt Ans(0);
        LL prev=0;
        Ans.f=f^(x<0),Ans.d=0,x=abs(x);
        for (int i=d;i>0;i--){
            prev=prev*mod+v[i];
            if (prev>=x)
                Ans.v[i]=prev/x,prev%=x,Ans.d=max(Ans.d,i);
        }
        if (Ans.d==0) 
            Ans.f=0;
        return Ans;
    }
    BigInt operator %(BigInt y){//取模运算 
        BigInt x=*this,minus;
        bool xfz=f^y.f;
        x.f=y.f=0,minus=y;
        if (x<y){
            x.f=xfz;
            return x;
        }
        while ((minus*10).smqu(x))
            minus=minus*10;
        while (minus.bgqu(y)){
            while (minus.smqu(x))
                x=x-minus;
            minus=minus/10;
        }
        x.f=xfz;
        if (x.d==0) 
            x.f=0;
        return x;
    }
    LL operator %(LL x){
        LL prev=0;
        bool flag=f^(x<0);
        x=abs(x);
        for (int i=d;i>0;i--)
            prev=prev*mod+v[i],prev%=x;
        if (flag) 
            prev=-prev;
        return prev;
    }
    BigInt operator ^(int x){
        BigInt Ans;
        Ans=1;
        if (x==0)
            return Ans;
        Ans=*this^(x/2);
        Ans=Ans*Ans;
        if (x&1)
            Ans=Ans**this;
        return Ans;
    }
}zero(0),one(1);
BigInt GcdY(BigInt x,BigInt y){
    return y!=zero?GcdY(y,x%y):x;
}
BigInt Gcd(BigInt x,BigInt y){
    x.f=y.f=0;
    if (x==zero)
        return y;
    if (y==zero)
        return x;
    return GcdY(x,y);
}
BigInt LcmY(BigInt x,BigInt y){
    return x/GcdY(x,y)*y;
}
BigInt Lcm(BigInt x,BigInt y){
    x.f=y.f=0;
    if (x==zero)
        return y;
    if (y==zero)
        return x;
    return LcmY(x,y);
}
BigInt abs(BigInt x){
    x.f=0;
    return x;
}
void read(char ch,BigInt &x){
    if (ch=='c'){
        char str[MaxLen];
        scanf("%s",str),x=str;
    }
    if (ch=='i'){
        int y;
        scanf("%d",&y),x=y;
    }
    if (ch=='L'){
        LL y;
        scanf("%lld",&y),x=y;
    }
}
void readint(BigInt &x,int &ret){
    scanf("%d",&ret),x=ret;
}
void readLL(BigInt &x,LL &ret){
    scanf("%lld",&ret),x=ret;
}
int main(){
    BigInt A,B;
    LL a,b;
    readLL(A,a),readLL(B,b);                    A.Print(' ');    B.Print(' ');
//    read('c',A),read('c',B);                    A.Print(' ');    B.Print(' ');
    printf("Gcd(A,B)=");Gcd(A,B).Print('\n');    A.Print(' ');    B.Print(' ');
    printf("Lcm(A,B)=");Lcm(A,B).Print('\n');    A.Print(' ');    B.Print(' ');
    printf("A*B=");(A*B).Print('\n');            A.Print(' ');    B.Print(' ');
    printf("A-B=");(A-B).Print('\n');            A.Print(' ');    B.Print(' ');
    printf("A+B=");(A+B).Print('\n');            A.Print(' ');    B.Print(' ');
    printf("A/B=");(A/B).Print('\n');            A.Print(' ');    B.Print(' ');
//    printf("A/b=");(A/b).Print('\n');            A.Print(' ');    B.Print(' ');
//    printf("A^b=");(A^b).Print('\n');            A.Print(' ');    B.Print(' ');
//    printf("A*b=");(A*b).Print('\n');            A.Print(' ');    B.Print(' ');
//    printf("A+b=");(A+b).Print('\n');            A.Print(' ');    B.Print(' ');
//    printf("A-b=");(A-b).Print('\n');            A.Print(' ');    B.Print(' ');
//    printf("A%b=");printf("%d\n",A%b);            A.Print(' ');    B.Print(' ');
    printf("A%B=");(A%B).Print('\n');            A.Print(' ');    B.Print(' ');
    printf("A<B?->");printf("%d\n",A<B);        A.Print(' ');    B.Print(' ');
    printf("A>B?->");printf("%d\n",A>B);        A.Print(' ');    B.Print(' ');
    printf("A<=B?->");printf("%d\n",A<=B);        A.Print(' ');    B.Print(' ');
    printf("A>=B?->");printf("%d\n",A>=B);        A.Print(' ');    B.Print(' ');
    printf("A==B?->");printf("%d\n",A==B);        A.Print(' ');    B.Print(' ');
    printf("A!=B?->");printf("%d\n",A!=B);        A.Print(' ');    B.Print(' ');
    printf("abs(A)=");abs(A).Print('\n');        A.Print(' ');    B.Print(' ');
    printf("abs(B)=");abs(B).Print('\n');        A.Print(' ');    B.Print(' ');
    printf("\n优先级判断:\n");                    A.Print(' ');    B.Print(' ');
    printf("A*B^2=");(A*B^2).Print('\n');        A.Print(' ');    B.Print(' ');//ans:A*B^2=(A*B)^2
    printf("A/A*B=");(A/A*B).Print('\n');        A.Print(' ');    B.Print(' ');//ans:A/A*B=B
    return 0;
}
View Code

高精度分数运算(基于上一份高精度整数运算)

struct BigDouble{
    BigInt a,b;
    void Print(){
        (*this).Smaller();
        if (a==zero){
            printf("0");
            return;
        }
        if (b==one)
            a.Print();
        else
            a.Print('/'),b.Print();
    }
    void Print(char ch){
        (*this).Smaller();
        if (a==zero){
            printf("0%c",ch);
            return;
        }
        if (b==one)
            a.Print(ch);
        else
            a.Print('/'),b.Print(ch);
    }
    void Smaller(){
        if (a==zero||b==zero)
            return;
//        a.Print('\n');b.Print('\n');
        BigInt gcd=Gcd(a,b);
//        puts("Small achieve");
        a=a/gcd,b=b/gcd;
//        puts("div adchive");
        if (b.f)
            a.f^=1,b.f^=1;
    }
    void operator = (BigInt x){
        a=x,b=one;
    }
    BigDouble operator * (BigDouble x){
        BigDouble ans;
        ans.a=a*x.a,ans.b=b*x.b;
        ans.Smaller();
        return ans;
    }
    BigDouble operator * (BigInt x){
        BigDouble ans;
        ans.a=x*a,ans.b=b;
        ans.Smaller();
        return ans;
    }
    BigDouble operator - (BigDouble x){
        BigDouble ans;
        BigInt lcm=Lcm(b,x.b),tt=lcm/b,tx=lcm/x.b;
//        BigInt lcm=one,tt=one,tx=one;
        ans.b=lcm,ans.a=a*tt-x.a*tx;
        ans.Smaller();
        return ans;
    }
    BigDouble operator / (BigInt x){
        BigDouble ans;
//        b.Print('\n');x.Print('\n');
        ans.a=a,ans.b=b*x;
//        puts("still alive");
        ans.Smaller();
        return ans;
    }
    BigDouble operator / (BigDouble x){
        BigDouble ans;
        ans.a=a*x.b,ans.b=b*x.a;
        ans.Smaller();
        return ans;
    }
}x[N];
View Code

猜你喜欢

转载自www.cnblogs.com/zhouzhendong/p/MoBan.html