1. 程式人生 > 實用技巧 >高精度合集(vector,帶低精)

高精度合集(vector,帶低精)

https://www.luogu.com.cn/problem/P1932

高精度合集(樸素)

高精度合集(NTT優化乘法)

高精度合集(vector)

高精度合集(vector,帶低精)

待補:壓位高精,多項式除法優化除法、取模

高精度除可以欽定選取前幾位後再進行除法(也許常數略小?)

Luogu1932 A+B A-B A*B A/B A%B Problem

高精度合集(vector,帶低精)

NTT優化乘法,vector,帶低精,無符號

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#define N 20005
#define M 40005
#define ll long long
#define ull unsigned long long
#define a hz.w
#define b kz.w
#define c kzkz.w
#define d kzzf.w
#define P 998244353
#define inv(x) ksm(x,P-2)
#define zero(x) (x.w[0]==1 && x.w[1]==0)
#define IT vector<int> :: iterator
using namespace std;
const ll lim=922337203685477578;
char orz[N];
int rev[M];
int G[2][25];
int e[M],f[M];
ll ten[25];
int ksm(int x,int y);
void NTT(int *g,int t,int s);
struct BigNumber
{
    vector<int>w;
    void set0()
    {
        w.clear();
        w.push_back(1),w.push_back(0);
    }
    void set1()
    {
        w.clear();
        w.push_back(1),w.push_back(1);
    }
    void setNum(ll x)
    {
        if (!x)
        {
            set0();
            return;
        }
        w.clear();
        w.push_back(0);
        int g=0;
        while (x)
        {
            w.push_back(x%10);
            x/=10;
            g++;
        }
        w[0]=g;
    }
    void read()
    {
        scanf("%s",orz);
        w.clear();
        w.push_back(strlen(orz));
        for (int i=w[0]-1;i>=0;i--)
            w.push_back(orz[i]-'0');
    }
}s,t;
BigNumber kz,kzkz,kzzf;
void write(BigNumber kz)
{
    for (int i=b[0];i>=1;i--)
        putchar(b[i]+'0');
    putchar('\n');
}
ll BigNumber_Turn_Number(BigNumber kz);
bool operator < (BigNumber hz,ll x)
{
    if (a[0]>19 || x<ten[a[0]])
        return false;
    if (x>=ten[a[0]+1])
        return true;
    for (int i=a[0];i>=1;i--)
        if (a[i]!=x/ten[i]%10)
            return a[i]<x/ten[i]%10;
    return false;
}
bool operator <= (BigNumber hz,ll x)
{
    if (a[0]>19 || x<ten[a[0]])
        return false;
    if (x>=ten[a[0]+1])
        return true;
    for (int i=a[0];i>=1;i--)
        if (a[i]!=x/ten[i]%10)
            return a[i]<x/ten[i]%10;
    return true;
}
bool operator > (BigNumber hz,ll x)
{
    if (a[0]>19 || x<ten[a[0]])
        return true;
    if (x>=ten[a[0]+1])
        return false;
    for (int i=a[0];i>=1;i--)
        if (a[i]!=x/ten[i]%10)
            return a[i]>x/ten[i]%10;
    return false;
}
bool operator >= (BigNumber hz,ll x)
{
    if (a[0]>19 || x<ten[a[0]])
        return true;
    if (x>=ten[a[0]+1])
        return false;
    for (int i=a[0];i>=1;i--)
        if (a[i]!=x/ten[i]%10)
            return a[i]>x/ten[i]%10;
    return true;
}
bool operator == (BigNumber hz,ll x)
{
    if (a[0]>19 || x<ten[a[0]])
        return false;
    if (x>=ten[a[0]+1])
        return false;
    for (int i=a[0];i>=1;i--)
        if (a[i]!=x/ten[i]%10)
            return false;
    return true;
}
bool operator != (BigNumber hz,ll x)
{
    if (a[0]>19 || x<ten[a[0]])
        return true;
    if (x>=ten[a[0]+1])
        return true;
    for (int i=a[0];i>=1;i--)
        if (a[i]!=x/ten[i]%10)
            return true;
    return false;
}
bool operator < (ll x,BigNumber hz)
{
    if (a[0]>19 || x<ten[a[0]])
        return true;
    if (x>=ten[a[0]+1])
        return false;
    for (int i=a[0];i>=1;i--)
        if (a[i]!=x/ten[i]%10)
            return a[i]>x/ten[i]%10;
    return false;
}
bool operator <= (ll x,BigNumber hz)
{
    if (a[0]>19 || x<ten[a[0]])
        return true;
    if (x>=ten[a[0]+1])
        return false;
    for (int i=a[0];i>=1;i--)
        if (a[i]!=x/ten[i]%10)
            return a[i]>x/ten[i]%10;
    return true;
}
bool operator > (ll x,BigNumber hz)
{
    if (a[0]>19 || x<ten[a[0]])
        return false;
    if (x>=ten[a[0]+1])
        return true;
    for (int i=a[0];i>=1;i--)
        if (a[i]!=x/ten[i]%10)
            return a[i]<x/ten[i]%10;
    return false;
}
bool operator >= (ll x,BigNumber hz)
{
    if (a[0]>19 || x<ten[a[0]])
        return false;
    if (x>=ten[a[0]+1])
        return true;
    for (int i=a[0];i>=1;i--)
        if (a[i]!=x/ten[i]%10)
            return a[i]<x/ten[i]%10;
    return true;
}
bool operator == (ll x,BigNumber hz)
{
    if (a[0]>19 || x<ten[a[0]])
        return false;
    if (x>=ten[a[0]+1])
        return false;
    for (int i=a[0];i>=1;i--)
        if (a[i]!=x/ten[i]%10)
            return false;
    return true;
}
bool operator != (ll x,BigNumber hz)
{
    if (a[0]>19 || x<ten[a[0]])
        return true;
    if (x>=ten[a[0]+1])
        return true;
    for (int i=a[0];i>=1;i--)
        if (a[i]!=x/ten[i]%10)
            return true;
    return false;
}
bool operator < (BigNumber hz,BigNumber kz)
{
    if (a[0]!=b[0])
        return a[0]<b[0];
    for (int i=a[0];i>=1;i--)
        if (a[i]!=b[i])
            return a[i]<b[i];
    return false;
}
bool operator <= (BigNumber hz,BigNumber kz)
{
    if (a[0]!=b[0])
        return a[0]<b[0];
    for (int i=a[0];i>=1;i--)
        if (a[i]!=b[i])
            return a[i]<b[i];
    return true;
}
bool operator > (BigNumber hz,BigNumber kz)
{
    if (a[0]!=b[0])
        return a[0]>b[0];
    for (int i=a[0];i>=1;i--)
        if (a[i]!=b[i])
            return a[i]>b[i];
    return false;
}
bool operator >= (BigNumber hz,BigNumber kz)
{
    if (a[0]!=b[0])
        return a[0]>b[0];
    for (int i=a[0];i>=1;i--)
        if (a[i]!=b[i])
            return a[i]>b[i];
    return true;
}
bool operator == (BigNumber hz,BigNumber kz)
{
    if (a[0]!=b[0])
        return false;
    for (int i=a[0];i>=1;i--)
        if (a[i]!=b[i])
            return false;
    return true;
}
bool operator != (BigNumber hz,BigNumber kz)
{
    if (a[0]!=b[0])
        return true;
    for (int i=a[0];i>=1;i--)
        if (a[i]!=b[i])
            return true;
    return false;
}
BigNumber operator + (BigNumber hz,ll x)
{
    for (int i=1;i<=a[0];i++)
    {
        x+=a[i];
        a[i]=x%10;
        x/=10;
    }
    while (x)
        a[0]++,a.push_back(x%10),x/=10;
    return hz;
}
BigNumber operator - (BigNumber hz,ll x)
{
    for (int i=1;i<=a[0];i++)
    {
        a[i]-=x%10;
        if (a[i]<0)
            a[i]+=10,a[i+1]--;
        x/=10;
    }
    IT it=a.end()-1;
    while (!(*it) && a[0]>1)
    {
        a[0]--;
        a.erase(it--);
    }
    return hz;
}
BigNumber operator * (BigNumber hz,ll x)
{
    ll jw=0;
    if (x<=lim)
    {
        for (int i=1;i<=a[0];i++)
        {
            jw+=x*a[i];
            a[i]=jw%10;
            jw/=10;
        }
        while (jw)
            a[0]++,a.push_back(jw%10),jw/=10;
    } else
    {
        ll rx=x/10;
        int tx=x%10,ri;
        for (int i=1;i<=a[0];i++)
        {
            ri=a[i];
            a[i]=a[i]*tx+jw%10;
            jw=jw/10+rx*ri+a[i]/10;
            a[i]%=10;
        }
        while (jw)
            a[0]++,a.push_back(jw%10),jw/=10;
    }
    return hz;
}
BigNumber operator / (BigNumber hz,ll x)
{
    e[0]=0;
    ll y=0;
    if (x<=lim)
    {
        for (int i=a[0];i;i--)
        {
            y=y*10+a[i];
            if (e[0] || y>=x)
                e[++e[0]]=y/x,y%=x;
        }
    } else
    {
        ull s;
        int ct;
        for (int i=a[0];i;i--)
        {
            if (y<=lim)
            {
                y=y*10+a[i];
                if (e[0] || y>=x)
                    e[++e[0]]=y/x,y%=x;
            } else
            {
                s=a[i],ct=0;
                for (int j=1;j<=10;j++)
                {
                    s+=y;
                    if (s>=x)
                        s-=x,ct++;
                }
                y=s;
                if (e[0] || ct)
                    e[++e[0]]=ct;
            }
        }
    }
    if (!e[0])
        e[0]++,e[1]=0;
    a.clear();
    a.push_back(e[0]);
    for (int i=e[0];i;i--)
        a.push_back(e[i]);
    return hz;
}
BigNumber operator % (BigNumber hz,ll x)
{
    ll y=0;
    if (x<=lim)
    {
        for (int i=a[0];i;i--)
            y=(y*10+a[i])%x;
    } else
    {
        ull s;
        for (int i=a[0];i;i--)
        {
            if (y<=lim)
                y=(y*10+a[i])%x; else
                {
                    s=a[i];
                    for (int j=1;j<=10;j++)
                    {
                        s+=y;
                        if (s>=x)
                            s-=x;
                    }
                    y=s;
                }
        }
    }
    hz.setNum(y);
    return hz;
}
BigNumber operator + (ll x,BigNumber hz)
{
    for (int i=1;i<=a[0];i++)
    {
        x+=a[i];
        a[i]=x%10;
        x/=10;
    }
    while (x)
        a[0]++,a.push_back(x%10),x/=10;
    return hz;
}
BigNumber operator - (ll x,BigNumber hz)
{
    x-=BigNumber_Turn_Number(hz);
    hz.setNum(x);
    return hz;
}
BigNumber operator * (ll x,BigNumber hz)
{
    ll jw=0;
    if (x<=lim)
    {
        for (int i=1;i<=a[0];i++)
        {
            jw+=x*a[i];
            a[i]=jw%10;
            jw/=10;
        }
        while (jw)
            a[0]++,a.push_back(jw%10),jw/=10;
    } else
    {
        ll rx=x/10;
        int tx=x%10,ri;
        for (int i=1;i<=a[0];i++)
        {
            ri=a[i];
            a[i]=a[i]*tx+jw%10;
            jw=jw/10+rx*ri+a[i]/10;
            a[i]%=10;
        }
        while (jw)
            a[0]++,a.push_back(jw%10),jw/=10;
    }
    return hz;
}
BigNumber operator / (ll x,BigNumber hz)
{
    if (x<hz)
    {
        hz.set0();
        return hz;
    }
    x/=BigNumber_Turn_Number(hz);
    hz.setNum(x);
    return hz;
}
BigNumber operator % (ll x,BigNumber hz)
{
    if (x<hz)
    {
        hz.setNum(x);
        return hz;
    }
    x%=BigNumber_Turn_Number(hz);
    hz.setNum(x);
    return hz;
}
BigNumber operator + (BigNumber hz,BigNumber kz)
{
    int ws=max(a[0],b[0]);
    int jw=0;
    for (int i=1;i<=ws;i++)
    {
        if (b[0]<i)
        {
            b[0]++;
            b.push_back(0);
        }
        if (a[0]>=i)
            b[i]+=a[i];
        b[i]+=jw;
        jw=b[i]/10;
        b[i]%=10;
    }
    while (jw)
    {
        b[0]++;
        b.push_back(jw%10);
        jw/=10;
    }
    return kz;
}
BigNumber operator - (BigNumber hz,BigNumber kz)
{
    int ws=max(a[0],b[0]);
    for (int i=1;i<=ws;i++)
    {
        if (b[0]<i)
            b.push_back(a[i]); else
            b[i]=a[i]-b[i];
        if (b[i]<0)
        {
            b[i]+=10;
            a[i+1]--;
        }
    }
    IT it=b.end()-1;
    while (!(*it) && ws>1)
    {
        ws--;
        b.erase(it--);
    }
    b[0]=ws;
    return kz;
}
BigNumber operator * (BigNumber hz,BigNumber kz)
{
	if (zero(hz) || zero(kz))
	{
		hz.set0();
		return hz;
	}
    int la=a[0],lb=b[0];
    int s=1,l=0;
    while (s<la+lb)
    {
        s <<=1;
        l++;
    }
    rev[0]=0;
    for (int i=1;i<s;i++)
        rev[i]=(rev[i >> 1] >> 1) | ((i & 1) << (l - 1));
    e[0]=f[0]=0;
    for (int i=1;i<=la;i++)
        e[i-1]=a[i];
    for (int i=1;i<=lb;i++)
        f[i-1]=b[i];
    for (int i=la;i<s;i++)
        e[i]=0;
    for (int i=lb;i<s;i++)
        f[i]=0;
    NTT(e,0,s);
    NTT(f,0,s);
    for (int i=0;i<s;i++)
        e[i]=(ll)e[i]*f[i]%P;
    NTT(e,1,s);
    int invs=inv(s);
    for (int i=s;i>=1;i--)
        e[i]=(ll)e[i-1]*invs%P;
    e[0]=0;
    for (int i=1;i<=la+lb;i++)
    {
        e[i+1]+=e[i]/10;
        e[i]%=10;
    }
    a[0]=la+lb;
    while (!e[a[0]] && a[0]>1)
        a[0]--;
    for (int i=1;i<=a[0];i++)
        if (la<i)
            a.push_back(e[i]); else
            a[i]=e[i];
    return hz;
}
BigNumber operator / (BigNumber hz,BigNumber kz)
{
    c.clear();
    c.push_back(0);
    for (int i=1;i<=a[0];i++)
        c.push_back(0);
    c[0]=a[0];
    kzzf.set0();
    for (int i=a[0];i>=1;i--)
    {
        if (!(d[0]==1 && d[1]==0))
        {
            d.push_back(0);
            for (int i=d[0];i>=1;i--)
                d[i+1]=d[i];
            d[1]=a[i];
            d[0]++;
        } else
            d[1]=a[i];
        while (kzzf>=kz)
        {
            kzzf=kzzf-kz;
            c[i]++;
        }
    }
    IT it=c.end()-1;
    while (!(*it) && c[0]>1)
    {
        c[0]--;
        c.erase(it--);
    }
    return kzkz;
}
BigNumber operator % (BigNumber hz,BigNumber kz)
{
    kzzf.set0();
    for (int i=a[0];i>=1;i--)
    {
        if (!(d[0]==1 && d[1]==0))
        {
            d.push_back(0);
            for (int i=d[0];i>=1;i--)
                d[i+1]=d[i];
            d[1]=a[i];
            d[0]++;
        } else
            d[1]=a[i];
        while (kzzf>=kz)
            kzzf=kzzf-kz;
    }
    return kzzf;
}
void operator += (BigNumber &kz,ll hz)
{
    kz=kz+hz;
}
void operator -= (BigNumber &kz,ll hz)
{
    kz=kz-hz;
}
void operator *= (BigNumber &kz,ll hz)
{
    kz=kz*hz;
}
void operator /= (BigNumber &kz,ll hz)
{
    kz=kz/hz;
}
void operator %= (BigNumber &kz,ll hz)
{
    kz=kz%hz;
}
void operator += (BigNumber &kz,BigNumber hz)
{
    kz=kz+hz;
}
void operator -= (BigNumber &kz,BigNumber hz)
{
    kz=kz-hz;
}
void operator *= (BigNumber &kz,BigNumber hz)
{
    kz=kz*hz;
}
void operator /= (BigNumber &kz,BigNumber hz)
{
    kz=kz/hz;
}
void operator %= (BigNumber &kz,BigNumber hz)
{
    kz=kz%hz;
}
BigNumber Number_Turn_BigNumber(ll x)
{
    if (x==0)
    {
        kz.set0();
        return kz;
    }
    b.clear();
    b.push_back(0);
    while (x)
    {
        b[0]++;
        b.push_back(x%10);
        x/=10;
    }
    return kz;
}
ll BigNumber_Turn_Number(BigNumber kz)
{
    ll y=0;
    for (int i=b[0];i>=1;i--)
        y=y*10+b[i];
    return y;
}
void NTT(int *q,int t,int s)
{
    for (int i=0;i<s;i++)
        if (i<rev[i])
            swap(q[i],q[rev[i]]);
    for (int mid=1,o=1;mid<s;mid <<=1,o++)
        for (int j=0;j<s;j+=(mid << 1))
        {
            int g=1;
            for (int k=0;k<mid;k++,g=(ll)g*G[t][o]%P)
            {
                int x=q[j+k],y=(ll)g*q[j+k+mid]%P;
                q[j+k]=(x+y)%P;
                q[j+k+mid]=(x-y+P)%P;
            }
        }
}
int ksm(int x,int y)
{
    int ans=1;
    while (y)
    {
        if (y & 1)
            ans=(ll)ans*x%P;
        x=(ll)x*x%P;
        y >>=1;
    }
    return ans;
}
void Pre()
{
    G[0][23]=ksm(3,(P-1)/(1 << 23));
    G[1][23]=inv(G[0][23]);
    for (int i=22;i>=1;i--)
    {
        G[0][i]=(ll)G[0][i+1]*G[0][i+1]%P;
        G[1][i]=(ll)G[1][i+1]*G[1][i+1]%P;
    }
    ten[1]=1;
    for (int i=2;i<=19;i++)
        ten[i]=ten[i-1]*10;
}
int main()
{
    Pre();
    s.read(),t.read();
    write(s+t);
    if (s<t)
        putchar('-'),write(t-s); else
        write(s-t);
    write(s*t);
    write(s/t);
    write(s%t);
    return 0;
}