高精度求助(常数)

P1303 A*B Problem

ppip @ 2023-01-26 19:20:55

在看到了该帖子之后,我尝试用模板重写楼主的代码,并 AC 了该题。

但我不太理解的是,这份代码奇慢无比,需要200ms才能完成 10^{2000} 级别的乘法。

大概可能是我的写法有问题?这样的话求教怎么实现常数更小。

#include <bits/stdc++.h>
using namespace std;
char buf[2005];
template <size_t T>
class Int {
public:
    using Rnt=Int<T-1>;
    using Rmt=Int<T>;
    Rnt H,E;
    Rnt high,low;
    Int(const Rnt& a,const Rnt& b):high{a},low{b},H{Rnt().H,Rnt().H},E{Rnt().E} {}
    explicit Int(const Rnt& a):Int{Rnt(),a} {}
    Int(long long p):Int{Rnt(),p} {}
    Int():Int{Rnt(),Rnt()} {}
    operator Rnt() const {
        return low;
    }
    // Int():Int{Rnt{0},Rnt(0)} {}
    Rmt operator+(const Rnt& b) const{
        Rmt ans = *this;
        ans.low=ans.low+b;
        if (ans.low>H) {
            ans.low.clearhigh();
            ans.high = ans.high+b.E;
        }
        return ans;
    }
    Rmt operator+(const Rmt& b) const{
        Rmt ans = *this;
        ans=ans+b.low;
        ans.high=ans.high+b.high;
        return ans;
    }
    bool operator==(const Rmt& n) const{
        return(high == n.high && low == n.low);
    }
    bool operator>(const Rmt& n) const{
        if (high > n.high) {
            return true;
        }
        else if (high == n.high) {
            if (low > n.low) {
                return true;
            }
        }
        return false;
    }
    void clearhigh() {
        high.clearhigh();
    }
};
template <>
class Int<0> {
public:
    using LL=Int<0>;
    static const long long H{99999999},E{1};
    long long p;
    operator long long() const {return p;}
    Int(long long _p=0):p{_p} {}
    Int(long long ppip,long long q):p{q} {}
    void clearhigh() {p-=H+1;}
};

template <size_t T>
Int<T+1> operator*(const Int<T> m,const Int<T> n) {
    using Rnt=Int<T>;
    using Rmt=Int<T+1>;
    Rnt q1{m.low*n.low},
        q2{m.high*n.low},
        q3{n.high*m.low},
        q4{m.high*n.high};
    Rmt ans;
    ans.low=q1;
    Rnt tmp{q2+q3+q1.high};
    ans.low.high=tmp.low;
    ans.high.low=tmp.high;
    if (ans.high.low>m.H) {
        ans.high.low.clearhigh();
        ans.high.high=ans.high.high+m.E;
    }
    ans.high=ans.high+q4;
    return ans;
}
template <>
Int<1> operator*(Int<0> m,Int<0> n) {return Int<1>{m.p*n.p/(m.H+1),m.p*n.p%(m.H+1)};}

template <size_t T>
void print(const Int<T> x,bool forv,ostream& os) {
    if (!forv&&x.high==Int<T-1>()) print(x.low,false,os);
    else print(x.high,forv,os),print(x.low,true,os);
}
template <>
void print(const Int<0> x,bool forv,ostream& os) {
    if (forv) os<<setw(8)<<setfill('0')<<x.p;
    else os<<x.p;
}
template <size_t T>
ostream& operator<<(ostream& os,const Int<T>& x) {
    print(x,false,os);
    return os;
}

template <size_t T>
void readbuf(Int<T>& x,int l,int r) {
    int mid{r-(8<<T-1)};
    readbuf(x.low,max(l,mid),r);
    if (mid>l) readbuf(x.high,l,mid);
}
template <>
void readbuf(Int<0>& x,int l,int r) {
    x.p=0;
    for (int i{l};i<r;++i)
        x.p=x.p*10+(buf[i]^48);
}
template <size_t T>
void read(Int<T>& x) {
    scanf("%s",buf);
    readbuf(x,0,strlen(buf));
}
template <typename T,typename ...Args>
void read(T& x,Args&... args) {read(x);read(args...);}

Int<2> a,b;
int main() {
    read(a,b);
    cout<<a*b<<endl;
    //print(a*b,false,cout);
    //cout<<a<<endl<<b<<endl<<a*b<<endl;
    return 0;
}

by ScaredQiu @ 2023-01-26 19:32:06

@ppip 可能是是cout的效率太低。

ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);

试试给cout加个速。


by Sincerin @ 2023-01-26 19:47:23

@ROADTOBURNTHESUN 楼主用了scanf 流的,如果再写 std::ios 加速会出大问题的。


by ScaredQiu @ 2023-01-26 21:21:53

@Sincerin 这个没关系,只要输入方式不混用,输出方式不混用就行。


by ScaredQiu @ 2023-01-26 21:22:44

不过我刚刚把lz的代码加上关闭同步交了一下反而更慢了,问题应该不出在这里。


by Sincerin @ 2023-01-26 21:31:51

@ROADTOBURNTHESUN 好吧,我是傻逼。(确实没混用)


|