大数操作(模板整理)

不得不说,51nod真的是个神奇的东西,不不不,我指的是他们提交的代码太太太优秀了>>>>>>>>>

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

首先贴一份某网友整理的万能大数c++模板(:orz  :

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <cassert>

using namespace std;

typedef long long ll;

class BigInteger
{
private:
    const static int MOD = (119 << 23) + 1;
    const static int root = 3;
    const static int invroot = 332748118;

    int *a;
    int length, sig;

    void apply(int length)
    {
        if (!length)
        {
            return ;
        }
        a = new int [length]();
        this -> length = length;
    }

    void destroy()
    {
        if (!length)
        {
            return ;
        }
        delete [] a;
        a = nullptr;
    }

    void resize(int length)
    {
        if (length == this->length)
        {
            return ;
        }
        if (!length)
        {
            return destroy();
        }
        int *aux = a;
        a = new int [length]();
        memcpy(a, aux, sizeof(int) * min(length, this->length));
        if (this->length)
        {
            delete [] aux;
        }
        this->length = length;
    }

    BigInteger(int length) : length(length), sig(0)
    {
        apply(length);
    }

    BigInteger(const BigInteger &p, int length) : length(length), sig(p.sig)
    {
        apply(length);
        memcpy(a, p.a, sizeof(int) * min(p.length, length));
    }

    bool absgreaterequal(const BigInteger &q) const &
    {
        if (length != q.length)
        {
            return length > q.length;
        }
        for (int i = length - 1; ~i; -- i)
        {
            if (a[i] > q.a[i])
            {
                return true;
            }
            if (a[i] < q.a[i])
            {
                return false;
            }
        }
        return true;
    }

    BigInteger operator << (const int &dis) const &
    {
        if (!sig)
        {
            return *this;
        }
        BigInteger ret(length + dis);
        memcpy(ret.a + dis, a, sizeof(int) * length);
        ret.sig = sig;

        return ret;
    }

    BigInteger operator >> (const int &dis) const &
    {
        if (dis >= length)
        {
            return BigInteger();
        }
        BigInteger ret(length - dis);
        memcpy(ret.a, a + dis, sizeof(int) * ret.length);
        ret.sig = sig;
        return ret;
    }

    int powermod(int a, int exp) const &
    {
        int ret = 1;
        for (; exp; exp >>= 1)
        {
            if (exp & 1)
            {
                ret = (ll) ret * a % MOD;
            }
            a = (ll) a * a % MOD;
        }
        return ret;
    }

    void NTT(int *a, int length, int type) const &
    {
        int len = -1;
        for (int x = length; x; ++len, x >>= 1) ;
        for (int i = 1, j = 0; i < length - 1; ++i)
        {
            for (int s = length; j ^= s >>= 1, ~j & s; ) ;
            if (i < j)
            {
                swap(a[i], a[j]);
            }
        }
        for (int i = 1; i <= len; ++ i)
        {
            for (int j = 0, unit = powermod(type == 1 ? root : invroot, (MOD - 1) >> i), szk = 1 << (i - 1); j < length; j += 1 << i)
            {
                for (int k = j, w = 1; k < j + szk; ++ k)
                {
                    int s = a[k], t = (ll) w * a[k + szk] % MOD;
                    a[k] = s + t >= MOD ? s + t - MOD : s + t;
                    a[k + szk] = s - t < 0 ? s - t + MOD : s - t;
                    w = (ll) w * unit % MOD;
                }
            }
        }
        if (type == 1)
        {
            return ;
        }
        int inv = powermod(length, MOD - 2);
        for (int i = 0; i < length; ++i)
        {
            a[i] = (ll) a[i] * inv % MOD;
        }
    }

    int divide(BigInteger &p, const int &q) const &
    {
        if (!q)
        {
            assert(-1);
        }
        if (!p.sig)
        {
            return 0;
        }
        ll remain = 0, x = abs(q);
        for (int i = length - 1; ~i; -- i)
        {
            remain = remain * 10 + p.a[i];
            p.a[i] = (int)(remain / x);
            remain %= x;
        }
        for (; p.length && !p.a[p.length - 1]; -- p.length) ;
        remain *= p.sig;
        p.sig *= q < 0 ? -1 : 1;
        if (!p.length)
        {
            p.sig = 0;
        }
        return (int)remain;
    }

public:
    BigInteger() : length(0), sig(0) { a = nullptr; }
    BigInteger(const BigInteger &p) : length(p.length), sig(p.sig)
    {
        apply(length), memcpy(a, p.a, sizeof(int) * length);
    }
    ~BigInteger() { destroy(); }
    int getlength() { return length; }
    bool positive() { return sig > 0; }
    bool iszero() { return !sig; }
    bool negative() { return sig < 0; }
    bool even() { return !sig || !(a[0] & 1); }

    BigInteger &operator = (const BigInteger &p)
    {
        destroy();
        apply(p.length);
        length = p.length;
        sig = p.sig;
        memcpy(a, p.a, sizeof(int) * length);
        return *this;
    }

    template <typename T>
    BigInteger &operator = (const T &p)
    {
        destroy();
        sig = p ? p > 0 ? 1 : -1 : 0;
        apply(40);
        int cnt = 0;
        for (T x = abs(p); x; x /= 10)
        {
            a[cnt++] = x % 10;
        }
        resize(cnt);
        return *this;
    }

    void read()
    {
        destroy();
        sig = 1;
        char ch = getchar();
        for ( ; ch < '0' || ch > '9'; ch = getchar())
        {
            if (ch == '-')
            {
                sig = -1;
            }
        }
        resize(1);
        int nowlength = 0;
        for (; ch >= '0' && ch <= '9'; ch = getchar())
        {
            a[nowlength++] = ch - '0';
            if (nowlength == length)
            {
                resize(length << 1);
            }
        }
        reverse(a, a + nowlength);
        for (; nowlength && !a[nowlength - 1]; --nowlength) ;
        resize(nowlength);
        sig = length ? sig : 0;
    }

    void write()
    {
        if (!sig)
        {
            return (void)putchar('0');
        }
        if (sig < 0)
        {
            putchar('-');
        }
        for (int i = length - 1; ~i; i--)
        {
            putchar(a[i] + '0');
        }
    }

    template <typename T>
    T tointeger()
    {
        T ret = 0;
        for (int i = length - 1; i >= 0; ++ i)
        {
            ret = ret * 10 + a[i];
        }
        return ret * sig;
    }

    bool operator == (const BigInteger &p) const &
    {
        if (sig != p.sig || length != p.length)
        {
            return false;
        }
        for (int i = 0; i < length; ++i)
        {
            if (a[i] != p.a[i])
            {
                return false;
            }
        }
        return true;
    }

    bool operator > (const BigInteger &p) const &
    {
        if (sig != p.sig)
        {
            return sig > p.sig;
        }
        if (length != p.length)
        {
            return length > p.length ^ sig == -1;
        }
        for (int i = length - 1; i >= 0; --i)
        {
            if (a[i] > p.a[i])
            {
                return sig > 0;
            }
            if (a[i] < p.a[i])
            {
                return sig < 0;
            }
        }
        return false;
    }

    BigInteger &operator ++ ()
    {
        resize(length + 1);
        sig >= 0 ? ++a[0] : --a[0];
        for (int i = 0; i < length - 1; ++i)
        {
            if (a[i] < 10 && a[i] >= 0)
            {
                break;
            }
            a[i] >= 10 ? (a[i] -= 10, ++a[i + 1]) : (a[i] += 10, --a[i + 1]);
        }
        for (; length && !a[length - 1]; --length) ;
        resize(length);
        sig = length ? sig >= 0 ? 1 : -1 : 0;
        return *this;
    }

    BigInteger &operator -- ()
    {
        sig = -sig;
        ++*this;
        sig = -sig;
        return *this;
    }

    BigInteger operator ++ (int)
    {
        BigInteger aux(*this);
        ++*this;
        return aux;
    }

    BigInteger operator -- (int)
    {
        BigInteger aux(*this);
        --*this;
        return aux;
    }

    BigInteger operator + (const BigInteger &p) const &
    {
        if (!p.sig)
        {
            return *this;
        }
        if (!sig)
        {
            return p;
        }
        bool type = true, flag = sig > 0;
        const BigInteger *aux = this, *aux1 = &p;
        if (sig != p.sig)
        {
            type = false;
            if (!absgreaterequal(p))
            {
                flag = !flag;
                swap(aux, aux1);
            }
        }
        BigInteger ret(*aux, max(length, p.length) + 1);
        for (int i = 0; i < ret.length - 1; ++i)
        {
            ret.a[i] += i < aux1->length ? type ? aux1->a[i] : -aux1->a[i] : 0;
            ret.a[i] >= 10 ? (ret.a[i] -= 10, ++ret.a[i + 1]) : ret.a[i] < 0 ? (ret.a[i] += 10, --ret.a[i + 1]) : 0;
        }
        for (; ret.length && !ret.a[ret.length - 1]; --ret.length) ;
        ret.resize(ret.length);
        ret.sig = ret.length ? flag ? 1 : -1 : 0;
        return ret;
    }

    BigInteger operator - () const &
    {
        BigInteger ret(*this);
        ret.sig = -ret.sig;
        return ret;
    }

    BigInteger operator - (const BigInteger &p) const & { return *this + (-p); }

    BigInteger operator * (const BigInteger &p) const &
    {
        if (!sig || !p.sig)
        {
            return BigInteger();
        }
        int n = length + p.length;
        int lengthret = 1;
        for (; lengthret < n; lengthret <<= 1) ;
        BigInteger ret(*this, lengthret);
        int *aux = new int [lengthret]();
        memcpy(aux, p.a, sizeof(int) * p.length);
        NTT(ret.a, lengthret, 1);
        NTT(aux, lengthret, 1);
        for (int i = 0; i < lengthret; ++i)
        {
            ret.a[i] = (ll) ret.a[i] * aux[i] % MOD;
        }
        NTT(ret.a, lengthret, -1);
        for (int i = 0; i < n - 1; i++)
        {
            ret.a[i + 1] += ret.a[i] / 10;
            ret.a[i] %= 10;
        }
        for (; n && !ret.a[n - 1]; --n) ;
        ret.resize(n);
        ret.sig = sig * p.sig;
        return ret;
    }

    BigInteger operator * (const int &p) const &
    {
        if (!p || !sig)
        {
            return BigInteger();
        }
        BigInteger ret(*this, length + 10);
        ll x = abs(p), remain = 0;
        for (int i = 0; i < length; ++ i)
        {
            remain += ret.a[i] * x;
            ret.a[i] = remain % 10;
            remain /= 10;
        }
        int nowlength = length;
        for (ret.a[nowlength] = (int)remain; ret.a[nowlength]; ++nowlength)
        {
            ret.a[nowlength + 1] = ret.a[nowlength] / 10;
            ret.a[nowlength] %= 10;
        }
        for (; nowlength && !ret.a[nowlength - 1]; --nowlength) ;
        ret.resize(nowlength);
        ret.sig = sig * (p < 0 ? -1 : 1);
        return ret;
    }

    BigInteger operator / (const BigInteger &p) const &
    {
        if (!p.sig)
        {
            assert(-1);
        }
        if (!sig || length < p.length)
        {
            return BigInteger();
        }
        int num = 0;
        for (int i = p.length - 1; i >= p.length - 3; --i)
        {
            (num *= 10) += i >= 0 ? p.a[i] : 0;
        }
        num = 100000 / num;
        int nowprecision = 1;
        BigInteger ret;
        ret = num;
        for (; nowprecision <= length - p.length; nowprecision <<= 1)
        {
            BigInteger aux((nowprecision << 1) + 3);
            aux.sig = 1;
            for (int i = p.length - aux.length; i < p.length; ++i)
            {
                aux.a[i - p.length + aux.length] = i >= 0 ? p.a[i] : 0;
            }
            aux = (aux * ret >> (nowprecision + 2)) * ret >> (nowprecision + 2);
            ret = (ret * 2 << nowprecision) - aux;
        }
        ret = ret * *this >> (p.length + nowprecision + 1);
        ret.sig = abs(ret.sig);
        BigInteger aux(p);
        aux.sig = abs(aux.sig);
        if (!absgreaterequal(ret * aux))
        {
            --ret;
        }
        else if (!absgreaterequal(++ret * aux))
        {
            --ret;
        }
        ret.sig *= sig * p.sig;
        return ret;
    }

    BigInteger operator / (const int &p) const &
    {
        BigInteger ret(*this);
        divide(ret, p);
        ret.resize(ret.length);
        return ret;
    }

    BigInteger sqrt() const &
    {
        if (sig < 0)
        {
            assert(-1);
        }
        if (!sig)
        {
            return *this;
        }
        int num = 0;
        for (int i = length - 1; i >= length - 8; --i)
        {
            (num *= 10) += i >= 0 ? a[i] : 0;
        }
        ll x = length & 1 ? 10000000000000ll : 100000000000000ll;
        num = std::sqrt(1.0 * x / num); //  命名空间不能省
        int nowprecision = 2;
        BigInteger ret;
        ret = num;
        for (; nowprecision <= (length >> 1) + 1; nowprecision = (nowprecision << 1) - 1)
        {
            BigInteger aux((nowprecision << 1) + 1 + (length & 1));
            aux.sig = 1;
            for (int i = length - aux.length; i < length; ++i)
            {
                aux.a[i - length + aux.length] = i >= 0 ? a[i] : 0;
            }
            aux = ((aux * ret >> (nowprecision + 1)) * ret >> (nowprecision + 1)) / 2;
            BigInteger aux1((nowprecision + 1) << 1);
            aux1.sig = 1;
            aux1.a[aux1.length - 1] = 1, aux1.a[aux1.length - 2] = 5;
            ret = ret * (aux1 - aux) >> (nowprecision + 2);
        }
        ret = ret * *this >> ((length >> 1) + nowprecision + 1);
        if (!absgreaterequal(ret * ret))
        {
            --ret;
        }
        else
        {
            ++ret;
            if (!absgreaterequal(ret * ret))
            {
                --ret;
            }
        }
        return ret;
    }

    BigInteger operator % (const BigInteger &p) const &
    {
        if (!p.sig)
        {
            assert(-1);
        }
        return *this - *this / p * p;
    }

    int operator % (const int &p) const &
    {
        if (!p)
        {
            assert(-1);
        }
        BigInteger aux(*this);
        return divide(aux, p);
    }

    friend BigInteger operator * (const int &q, const BigInteger &p) { return p * q; }
    BigInteger &operator += (const BigInteger &p) { *this = *this + p; return *this; }
    BigInteger &operator -= (const BigInteger &p) { *this = *this - p; return *this; }
    BigInteger &operator *= (const BigInteger &p) { *this = *this * p; return *this; }
    BigInteger &operator *= (const int &p) { *this = *this * p; return *this; }
    BigInteger &operator /= (const BigInteger &p) { *this = *this / p; return *this; }
    BigInteger &operator /= (const int &p) { *this = *this / p; return *this; }
    BigInteger &operator %= (const BigInteger &p) { *this = *this % p; return *this; }
    BigInteger &operator %= (const int &p) { *this = *this % p; return *this; }

    template <typename T> 
    BigInteger power(T exp) const &
    {
        BigInteger ret = 1, aux(*this);
        for (; exp; exp >>= 1)
        {
            if (exp & 1)
            {
                ret *= aux;
            }
            aux *= aux;
        }

        return ret;
    }
};
BigInteger a;
int main()
{
    a.read();a.write();
    return 0;
}
View Code

膜拜膜拜

一. 当然大数的加减乘除均可以用以上万能模板,内部用NTT优化>>>,其次可以用java拍大数>>>

二.大数的开平方根:

 1.万能模板

 2.java的牛顿迭代:(计蒜课2018焦作网络赛Participate in E-sports)

import java.math.BigInteger;
import java.math.*;
import java.math.BigInteger;
import java.util.Scanner;
import java.util.*; 
public class Main
{
    public static boolean is_(String s,BigInteger x){
          BigInteger remain=BigInteger.ZERO;
          BigInteger odd=BigInteger.ZERO;
          BigInteger ans=BigInteger.ZERO;
          int group=0,k=0;
          if(s.length()%2==1)
          {
              group=s.charAt(0)-'0';
              k=-1;
          }
          else
          {
                  group=(s.charAt(0)-'0')*10+s.charAt(1)-'0';
                  k=0;
          }
          for(int j=0;j<(s.length()+1)/2;j++)
          {
                  if(j!=0)
                  group=(s.charAt(j*2+k)-'0')*10+s.charAt(j*2+k+1)-'0';
                  odd=BigInteger.valueOf(20).multiply(ans).add(BigInteger.ONE);
                  remain=BigInteger.valueOf(100).multiply(remain).add(BigInteger.valueOf(group));
                  int count=0;
                  while(remain.compareTo(odd)>=0)
                  {
                         count++;
                         remain=remain.subtract(odd);
                         odd=odd.add(BigInteger.valueOf(2));
                  }
                  ans=ans.multiply(BigInteger.TEN).add(BigInteger.valueOf(count));
          }
          //System.out.println(x+" "+ans);
        return x.equals(ans.multiply(ans));
    }
       public static void main(String[] args) 
       {
               Scanner cin=new Scanner(System.in);
               String s1,s2;
               int T = cin.nextInt();
               for (int cas = 1; cas <= T; ++cas) {
                   s1=cin.next();BigInteger s_1=new BigInteger(s1);
                   BigInteger s_2=s_1.subtract(BigInteger.ONE);
                   s_2=s_2.multiply(s_1);s_2=s_2.shiftRight(1);
                   s2=s_2.toString();
                   boolean nIsSquare = is_(s1,s_1);
                   boolean mIsSquare = is_(s2,s_2);
                   if (nIsSquare && mIsSquare) {
                       System.out.println("Arena of Valor");
                   } else if (nIsSquare && !mIsSquare) {
                       System.out.println("Hearth Stone");
                   } else if (!nIsSquare && mIsSquare) {
                       System.out.println("Clash Royale");
                   } else {
                       System.out.println("League of Legends");
                   }
               }
              cin.close();
      }
}
View Code

  主要是java在大数与字符串之间来回转换太方便了>>效率贼高

   3.c++的手动开根:(zoj4005 luckman)

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int l;char ans[1000];int num=0;
int work(int o,char *O,int I)
{
    char c,*D=O;
    if(o>0)
    {
        for(l=0;D[l];D[l++]-=10)
        {
            D[l++]-=120;
            D[l]-=110;
            while(!work(0,O,l))
                D[l]+=20;
            //putchar((D[l]+1032)/20);
            ans[num++]=(D[l]+1032)/20;
        }
        //putchar(10);
        //ans[num++]='1';ans[num++]='0';
    }
    else
    {
        c=o+(D[I]+82)%10-(I>l/2)*(D[I-l+I]+72)/10-9;
        D[I]+=I<0 ? 0 : !(o=work(c/10,O,I-1))*((c+999)%10-(D[I]+92)%10);
    }
    return o;
}
 
int main()
{
    char s[1200];
    int t;scanf("%d",&t);
    while(t--){
        num=0;
    s[0]='0';
    scanf("%s",s+1);
    if(strlen(s)%2 == 1)
        work(2,s+1,0);
    else
        work(2,s,0);
    ans[num]='\0';
    //printf("%s\n",ans);
    int tmp=ans[num-1]-'0';
    if(tmp&1) printf("1\n");
    else printf("0\n");
    }
    return 0;
}
View Code

  4.带精度的牛顿迭代开根..(不得不说...效率低了好多....大数运算的时间消耗一直没有搞清楚)

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        int T = cin.nextInt();
        for(int i = 1; i <= T; i++) {
            
            String s = cin.next();
            BigInteger n = new BigInteger(s);
            BigInteger m = n.multiply(n.subtract(BigInteger.ONE)).shiftRight(1);
            int f=0,f2=0;
            if(is_(n)==1) f2=1;
            if(is_(m)==1) f=1;
            if(f==1&&f2==1) {
                System.out.println("Arena of Valor");
            }
            else if(f==1&&f2==0) {
                System.out.println("Clash Royale");
            }
            else if(f==0&&f2==1) {
                System.out.println("Hearth Stone");
            }
            else {
                System.out.println("League of Legends");
            }
        }
    }
    public static int is_(BigInteger xx)
    {
        BigDecimal x=new BigDecimal(xx);
        BigDecimal n1=x.divide(BigDecimal.valueOf(2));
        BigDecimal ans=BigDecimal.ZERO;
        while((n1.multiply(n1).subtract(x)).abs().compareTo(BigDecimal.valueOf(0.001))==1)
        {
            BigDecimal s1=x.divide(n1,2000,BigDecimal.ROUND_HALF_UP);
            BigDecimal s2=n1.add(s1);
            n1=s2.divide(BigDecimal.valueOf(2),2000,BigDecimal.ROUND_HALF_UP);
            
        }
        ans=n1;
        BigInteger rt =new BigInteger(ans.toString().split("\\.")[0]);
        if(xx.equals(rt.multiply(rt))) return 1;
        else return 0;
    }
}
View Code

 5.大数之间进制的转换(java):

import java.math.BigInteger;
import java.util.Scanner;

public class Main {
    public static void main(String args[]) {
        Scanner sc = new Scanner(System.in);
        //将36进制转换为10进制输出
        //方法1:
        String s = sc.next();
        System.out.println(change(s, 36, 10));
        sc.close();
        //方法2
        BigInteger a=sc.nextBigInteger(36);
        System.out.println(a);
        
    }
    //进制之间的转换
    private static String change(String a1,int i,int j) {
        return new java.math.BigInteger(a1,i).toString(j);
    }
}
View Code

6.大数的阶乘处理:(待补-------)

 

猜你喜欢

转载自www.cnblogs.com/vainglory/p/9670905.html