#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;

struct DecimalBig {
    vector<int> intPart;
    vector<int> decPart;
    int sign;
    int decLen;

    DecimalBig() : sign(1), decLen(250) {}
    DecimalBig(long long x, int dl = 250) : decLen(dl) {
        sign = 1;
        if (x < 0) {
            sign = -1;
            x = -x;
        }
        intPart.clear();
        decPart.clear();
        if (x == 0) intPart.push_back(0);
        while (x) {
            intPart.push_back(x % 10);
            x /= 10;
        }
    }
    DecimalBig(const string &s, int dl = 250) : decLen(dl) {
        sign = 1;
        intPart.clear();
        decPart.clear();
        int dotPos = -1;
        int st = 0;
        if (s[0] == '-') {
            sign = -1;
            st = 1;
        }
        for (int i = st; i < s.size(); i++) {
            if (s[i] == '.') {
                dotPos = i;
                break;
            }
        }
        if (dotPos == -1) {
            for (int i = s.size() - 1; i >= st; i--)
                intPart.push_back(s[i] - '0');
        } else {
            for (int i = dotPos - 1; i >= st; i--)
                intPart.push_back(s[i] - '0');
            for (int i = dotPos + 1; i < s.size() && decPart.size() < decLen; i++)
                decPart.push_back(s[i] - '0');
        }
        trim();
    }

    void trim() {
        while (intPart.size() > 1 && intPart.back() == 0)
            intPart.pop_back();
        while (decPart.size() > 0 && decPart.back() == 0)
            decPart.pop_back();
        if (intPart.size() == 1 && intPart[0] == 0 && decPart.empty())
            sign = 1;
    }

    void fillDec(int len) {
        while (decPart.size() < len) decPart.push_back(0);
    }

    void roundDec(int keep) {
        if ((int)decPart.size() <= keep) return;
        int carry = decPart[keep] >= 5 ? 1 : 0;
        decPart.resize(keep);
        int pos = 0;
        while (carry && pos < decPart.size()) {
            int sum = decPart[pos] + carry;
            decPart[pos] = sum % 10;
            carry = sum / 10;
            pos++;
        }
        if (carry) {
            pos = 0;
            while (carry && pos < intPart.size()) {
                int sum = intPart[pos] + carry;
                intPart[pos] = sum % 10;
                carry = sum / 10;
                pos++;
            }
            if (carry) intPart.push_back(1);
        }
        trim();
    }

    vector<int> toAllInt() const {
        vector<int> res = intPart;
        for (auto c : decPart) res.insert(res.begin(), c);
        return res;
    }

    bool absGreater(const DecimalBig &b) const {
        int maxDec = max(decPart.size(), b.decPart.size());
        DecimalBig aTmp = *this, bTmp = b;
        aTmp.fillDec(maxDec);
        bTmp.fillDec(maxDec);
        vector<int> aAll = aTmp.toAllInt();
        vector<int> bAll = bTmp.toAllInt();
        if (aAll.size() != bAll.size()) return aAll.size() > bAll.size();
        for (int i = aAll.size() - 1; i >= 0; i--)
            if (aAll[i] != bAll[i]) return aAll[i] > bAll[i];
        return false;
    }

    bool absEqual(const DecimalBig &b) const {
        return !absGreater(b) && !b.absGreater(*this);
    }

    DecimalBig absAdd(const DecimalBig &b) const {
        DecimalBig res;
        res.decLen = max(decLen, b.decLen);
        int maxDec = max(decPart.size(), b.decPart.size());
        DecimalBig aTmp = *this, bTmp = b;
        aTmp.fillDec(maxDec);
        bTmp.fillDec(maxDec);
        vector<int> aAll = aTmp.toAllInt();
        vector<int> bAll = bTmp.toAllInt();
        vector<int> sumAll;
        int carry = 0;
        int maxLen = max(aAll.size(), bAll.size());
        for (int i = 0; i < maxLen || carry; i++) {
            int va = (i < aAll.size()) ? aAll[i] : 0;
            int vb = (i < bAll.size()) ? bAll[i] : 0;
            int s = va + vb + carry;
            sumAll.push_back(s % 10);
            carry = s / 10;
        }
        res.decPart.clear();
        res.intPart.clear();
        for (int i = 0; i < maxDec && i < sumAll.size(); i++)
            res.decPart.push_back(sumAll[i]);
        for (int i = maxDec; i < sumAll.size(); i++)
            res.intPart.push_back(sumAll[i]);
        res.roundDec(res.decLen);
        return res;
    }

    DecimalBig absSub(const DecimalBig &b) const {
        DecimalBig res;
        res.decLen = max(decLen, b.decLen);
        int maxDec = max(decPart.size(), b.decPart.size());
        DecimalBig aTmp = *this, bTmp = b;
        aTmp.fillDec(maxDec);
        bTmp.fillDec(maxDec);
        vector<int> aAll = aTmp.toAllInt();
        vector<int> bAll = bTmp.toAllInt();
        vector<int> subAll;
        int borrow = 0;
        for (int i = 0; i < aAll.size(); i++) {
            int va = aAll[i] - borrow;
            int vb = (i < bAll.size()) ? bAll[i] : 0;
            borrow = 0;
            if (va < vb) {
                va += 10;
                borrow = 1;
            }
            subAll.push_back(va - vb);
        }
        res.decPart.clear();
        res.intPart.clear();
        for (int i = 0; i < maxDec && i < subAll.size(); i++)
            res.decPart.push_back(subAll[i]);
        for (int i = maxDec; i < subAll.size(); i++)
            res.intPart.push_back(subAll[i]);
        res.roundDec(res.decLen);
        return res;
    }

    DecimalBig operator+(const DecimalBig &b) const {
        DecimalBig res;
        if (sign == b.sign) {
            res = absAdd(b);
            res.sign = sign;
        } else {
            if (absGreater(b)) {
                res = absSub(b);
                res.sign = sign;
            } else {
                res = b.absSub(*this);
                res.sign = -b.sign;
            }
        }
        return res;
    }

    DecimalBig operator-(const DecimalBig &b) const {
        DecimalBig tmp = b;
        tmp.sign *= -1;
        return *this + tmp;
    }

    DecimalBig operator*(const DecimalBig &b) const {
        DecimalBig res;
        res.decLen = decLen + b.decLen;
        res.sign = sign * b.sign;
        vector<int> aAll = toAllInt();
        vector<int> bAll = b.toAllInt();
        vector<int> mulAll(aAll.size() + bAll.size(), 0);
        for (int i = 0; i < aAll.size(); i++) {
            int carry = 0;
            for (int j = 0; j < bAll.size() || carry; j++) {
                int vb = (j < bAll.size()) ? bAll[j] : 0;
                long long val = mulAll[i + j] + 1LL * aAll[i] * vb + carry;
                mulAll[i + j] = val % 10;
                carry = val / 10;
            }
        }
        int totalDec = decPart.size() + b.decPart.size();
        res.decPart.clear();
        res.intPart.clear();
        for (int i = 0; i < totalDec && i < mulAll.size(); i++)
            res.decPart.push_back(mulAll[i]);
        for (int i = totalDec; i < mulAll.size(); i++)
            res.intPart.push_back(mulAll[i]);
        res.roundDec(decLen);
        res.trim();
        return res;
    }

    using BigIntVec = vector<int>;
    static bool bigVecCmp(const BigIntVec &a, const BigIntVec &b) {
        if (a.size() != b.size()) return a.size() > b.size();
        for (int i = a.size()-1; i >= 0; i--)
            if (a[i] != b[i]) return a[i] > b[i];
        return false;
    }
    static BigIntVec bigVecSub(const BigIntVec &a, const BigIntVec &b) {
        BigIntVec res;
        int bor = 0;
        for (int i = 0; i < a.size(); i++) {
            int va = a[i] - bor;
            int vb = (i < b.size()) ? b[i] : 0;
            bor = 0;
            if (va < vb) { va += 10; bor = 1; }
            res.push_back(va - vb);
        }
        while (res.size()>1 && res.back()==0) res.pop_back();
        return res;
    }
    static BigIntVec bigVecMul10(BigIntVec x) {
        x.insert(x.begin(), 0);
        return x;
    }
    static int tryDiv(BigIntVec &rem, const BigIntVec &div)
    {
        int l=0,r=9,ans=0;
        BigIntVec base=div;
        while(l<=r)
        {
            int mid=(l+r)/2;
            BigIntVec mul=base;
            int carry=0;
            for(auto &x:mul)
            {
                long long v=1LL*x*mid+carry;
                x=v%10;
                carry=v/10;
            }
            if(carry) mul.push_back(carry);
            if(bigVecCmp(rem,mul)||!bigVecCmp(mul,rem))
            {
                ans=mid;
                l=mid+1;
            }
            else
            {
                r=mid-1;
            }
        }
        BigIntVec sub;
        int borrow=0;
        for(int i=0;i<rem.size();i++)
        {
            long long val=1LL*div[i]*ans+borrow;
            int d=rem[i]-(val%10);
            borrow=val/10;
            if(d<0) {d+=10;borrow++;}
            sub.push_back(d);
        }
        while(sub.size()>1&&sub.back()==0) sub.pop_back();
        rem=sub;
        return ans;
    }

    DecimalBig operator/(const DecimalBig &b) const {
        if (b.intPart.size()==1 && b.intPart[0]==0 && b.decPart.empty()) {
            cerr<<"Error: Division by zero!"<<endl;
            exit(1);
        }
        DecimalBig res;
        res.decLen = decLen;
        res.sign = sign * b.sign;

        BigIntVec A = this->toAllInt();
        BigIntVec B = b.toAllInt();
        int shiftDec = (int)decPart.size() - (int)b.decPart.size();

        reverse(A.begin(), A.end());
        reverse(B.begin(), B.end());
        BigIntVec qInt, rem;
        for (int d : A) {
            rem.push_back(d);
            reverse(rem.begin(), rem.end());
            int num = tryDiv(rem, B);
            qInt.push_back(num);
            reverse(rem.begin(), rem.end());
        }
        reverse(qInt.begin(), qInt.end());
        while(qInt.size()>1 && qInt.back()==0) qInt.pop_back();
        res.intPart = qInt;

        vector<int> qDec;
        while((int)qDec.size() < res.decLen) {
            rem = bigVecMul10(rem);
            int num = tryDiv(rem, B);
            qDec.push_back(num);
        }
        res.decPart = qDec;

        if(shiftDec > 0) {
            for(int i=0;i<shiftDec;i++){
                if(res.decPart.empty()) break;
                res.intPart.insert(res.intPart.begin(), res.decPart[0]);
                res.decPart.erase(res.decPart.begin());
            }
        }else if(shiftDec < 0){
            int s = -shiftDec;
            for(int i=0;i<s;i++){
                if(res.intPart.size()<=1 && res.intPart[0]==0) break;
                res.decPart.insert(res.decPart.begin(), res.intPart[0]);
                res.intPart.erase(res.intPart.begin());
            }
        }

        res.roundDec(res.decLen);
        res.trim();
        return res;
    }

    DecimalBig operator%(const DecimalBig &b) const {
        DecimalBig q = *this / b;
        DecimalBig res = *this - q * b;
        return res;
    }

    DecimalBig& operator+=(const DecimalBig &b) {
        *this = *this + b;
        return *this;
    }
    DecimalBig& operator-=(const DecimalBig &b) {
        *this = *this - b;
        return *this;
    }
    DecimalBig& operator*=(const DecimalBig &b) {
        *this = *this * b;
        return *this;
    }
    DecimalBig& operator/=(const DecimalBig &b) {
        *this = *this / b;
        return *this;
    }
    DecimalBig& operator%=(const DecimalBig &b) {
        *this = *this % b;
        return *this;
    }

    bool operator>(const DecimalBig &b) const {
        if (sign == 1 && b.sign == -1) return true;
        if (sign == -1 && b.sign == 1) return false;
        if (sign == 1) return absGreater(b);
        else return b.absGreater(*this);
    }
    bool operator<(const DecimalBig &b) const { return b > *this; }
    bool operator==(const DecimalBig &b) const {
        if (sign != b.sign) return false;
        return absEqual(b);
    }
    bool operator!=(const DecimalBig &b) const { return !(*this == b); }
    bool operator>=(const DecimalBig &b) const { return (*this > b) || (*this == b); }
    bool operator<=(const DecimalBig &b) const { return (*this < b) || (*this == b); }

    friend ostream &operator<<(ostream &os, const DecimalBig &x) {
        if (x.sign == -1) os << '-';
        if (x.intPart.empty()) os << 0;
        else for (int i = x.intPart.size() - 1; i >= 0; i--) os << x.intPart[i];
        if (!x.decPart.empty()) {
            os << '.';
            for (int v : x.decPart) os << v;
        }
        return os;
    }
      friend istream &operator>>(istream &is, DecimalBig &x) {
        string s;
        is >> s;
        x = DecimalBig(s, x.decLen);
        return is;
    }    DecimalBig& operator++(){
        *this=*this+DecimalBig("1");
        return *this;
    }
    DecimalBig operator++(int){
        DecimalBig tmp=*this;
        ++(*this);
        return tmp;
    }
    DecimalBig& operator--(){
        *this=*this-DecimalBig("1");
        return *this;
    }
    DecimalBig operator--(int){
        DecimalBig tmp=*this;
        --(*this);
        return tmp;
    }
};

int main() {
    DecimalBig a("10", 8);
    DecimalBig b("3", 8);
    cout << "初始 a = " << a << endl;
    a += b;
    cout << "a += 3 -> " << a << endl;
    a -= DecimalBig("2");
    cout << "a -= 2 -> " << a << endl;
    a *= DecimalBig("1.5");
    cout << "a *= 1.5 -> " << a << endl;
    a /= DecimalBig("2");
    cout << "a /= 2 -> " << a << endl;
    a %= DecimalBig("4");
    cout << "a %= 4 -> " << a << endl;

    DecimalBig x("10"),y("10"),z("3");
    DecimalBig ans = x + y / z;
    cout<<"10 + 10 / 3 = "<<ans<<endl;
    DecimalBig ans2 = (x+y)/z;
    cout<<"(10+10)/3 = "<<ans2<<endl;
    return 0;
}

@