代码存档

皎月半洒花

2020-05-04 16:37:57

Personal

内部包含了: 1、压 8 位的高精度加、减、乘、除、gcd。其中除法指高精除高精。 2、分式计算。包含高精度通分。 3、某道题的部分代码。 PS: 由于题目特性保证了都是正整数,所以并不需要严格判断正负,于是中间省略了一些。 ```cpp #include <map> #include <cmath> #include <queue> #include <stack> #include <bitset> #include <cstdio> #include <vector> #include <cassert> #include <cstring> #include <iostream> #include <algorithm> using namespace std ; #define fr first #define sc second #define ins insert #define p_b push_back #define ls (rt << 1) #define rs (rt << 1 | 1) #define to(k) E[k].to #define val(k) E[k].val #define next(k) E[k].next #define il inline #define rg register typedef double db ; typedef long long ll ; typedef long double ldb ; typedef stack <int> sint ; typedef queue <int> qint ; typedef vector <int> vint ; typedef map <int, int> mint ; typedef pair <int, int> pint ; const db eps = 1e-7 ; const int N = 5010 ; const int M = 10010 ; const int P = 10000 ; const int Inf = 1000000007 ; const int Fni = -1000000007 ; il int qr(){ int r = 0, f = 1 ; char c = getchar() ; while (c > '9' || c < '0'){ if (c == '-') f = -1 ; c = getchar() ; } while (c <= '9' && c >= '0'){ r = (r << 1) + (r << 3) + c - '0', c = getchar() ; } return r * f ; } template <typename T> void debug(T *const tp, int minn, int maxn, char v = ' ', char c = '\n'){ for (int i = minn ; i <= maxn ; ++ i) cout << tp[i] << v ; cout << c ; } int cnt ; int head[N] ; struct Edge{ int to ; int val ; int next ; }E[N * 2] ; il void add_e(int x, int y, int w = 0){ to(++ cnt) = y ; val(cnt) = w ; next(cnt) = head[x] ; head[x] = cnt ; } template <typename T> il void chkmin(T &x, T y){ x = x > y ? y : x ; } template <typename T> il void chkmax(T &x, T y){ x = x < y ? y : x ; } template <typename T> il void add(T &x, T y, T mod){ x += y ; x = x >= mod ? x - mod : x ; } template <typename T> il void dec(T &x, T y, T mod){ x -= y ; x = x < 0 ? x + mod : x ; } template <typename T> il T addn(T x, T y, T mod){ x += y ; return (x = x > mod ? x - mod : x) ; } template <typename T> il T decn(T x, T y, T mod){ x -= y ; return (x = x < 0 ? x + mod : x) ; } const ll Base = 100000000 ; int get_L(int x){ int ret = 0 ; if (!x) return 1 ; while (x) ret ++, x /= 10 ; return ret ; } struct Big_Num{ ll v[2051] ; bool mk ; int len, lent ; void reset(){ len = 0, mk = 0, memset(v, 0, sizeof(v)) ; } void out_put(){ if (mk && !(len <= 1 && !v[1])) putchar('-') ; for (int i = len ; i >= 1 ; -- i){ if (i == len){ printf("%lld", v[i]) ; continue ; } for (int j = 1 ; j <= 8 - get_L(v[i]) ; ++ j) putchar('0') ; printf("%lld", v[i]) ; } //puts("") ; } template <typename T> void set_v(T x){ if (x < 0) mk = 1, x = -x ; while (x) v[++ len] = x % Base, x /= Base ; lent = (len - 1) * 8 + get_L(x) ; } void set_v(char *x, int L){ int p = 0 ; reset() ; if (x[1] == '-') ++ p, mk = 1 ; len = (L - p) / 8 + (((L - p) % 8) > 0) ; for (int i = L, k = len ; i >= p + 1 ; i -= 8, -- k){ for (int j = min(i - p, 8) ; j >= 1 ; -- j) v[k] = v[k] * 10ll + (x[i - j + 1] - '0') ; } reverse(v + 1, v + len + 1) ; lent = L - p ; } Big_Num friend operator ~ (Big_Num A){ A.mk ^= 1 ; return A ; } bool friend operator ^ (const Big_Num & A, const Big_Num & B){ if (A.len != B.len) return 0 ; for (int i = 1 ; i <= A.len ; ++ i) if (A.v[i] != B.v[i]) return 0 ; return 1 ; } bool friend operator < (const Big_Num & A, const Big_Num & B) ; bool friend operator > (const Big_Num & A, const Big_Num & B) ; Big_Num friend operator + (const Big_Num & A, const Big_Num & B) ; Big_Num friend operator - (const Big_Num & A, const Big_Num & B) ; il bool friend operator < (const Big_Num & A, const Big_Num & B){ if (A.len < B.len) return 1 ; else if (A.len > B.len) return 0 ; for (int i = A.len ; i >= 1 ; -- i) if (A.v[i] < B.v[i]) return 1 ; else if (A.v[i] > B.v[i]) return 0 ; return 0 ; } il bool friend operator > (const Big_Num & A, const Big_Num & B){ if (A.len < B.len) return 0 ; else if (A.len > B.len) return 1 ; for (int i = A.len ; i >= 1 ; -- i) if (A.v[i] > B.v[i]) return 1 ; else if (A.v[i] < B.v[i]) return 0 ; return 0 ; } il bool friend operator <= (const Big_Num & A, const Big_Num & B){ if (A.len < B.len) return 1 ; else if (A.len > B.len) return 0 ; for (int i = A.len ; i >= 1 ; -- i) if (A.v[i] < B.v[i]) return 1 ; else if (A.v[i] > B.v[i]) return 0 ; return 1 ; } il bool friend operator >= (const Big_Num & A, const Big_Num & B){ if (A.len < B.len) return 0 ; else if (A.len > B.len) return 1 ; for (int i = A.len ; i >= 1 ; -- i) if (A.v[i] > B.v[i]) return 1 ; else if (A.v[i] < B.v[i]) return 0 ; return 1 ; } il Big_Num friend operator - (const Big_Num & A, const Big_Num & B){ Big_Num res ; res.reset() ; Big_Num p, q, t ; p = A, q = B ; if (p.lent < q.lent) { return (~ (q - p)) ; } for (rg int i = 1 ; i <= p.len ; ++ i) res.v[i] = p.v[i] - q.v[i] ; for (rg int i = 1 ; i <= p.len ; ++ i) if (res.v[i] < 0) res.v[i + 1] --, res.v[i] += Base ; res.len = p.len ; res.v[0] = -1 ; for (rg int i = res.len + 20 ; i >= 0 ; -- i) if (res.v[i]) { res.len = i ; break ; } if (!res.len) res.len ++ ; if (res.v[res.len] < 0) res.mk = 1, res.len --, res.v[res.len] = Base - res.v[res.len] ; res.lent = (res.len - 1) * 8 + get_L(res.v[res.len]) ; return res ; } il Big_Num friend operator + (const Big_Num & A, const Big_Num & B){ Big_Num res ; res.reset() ; Big_Num p, q ; if (A.len > B.len) p = A, q = B ; else p = B, q = A ; if (p.mk && q.mk) res.mk = 1 ; else if (p.mk && !q.mk) { p.mk = 0 ; return (q - p) ; } else if (!p.mk && q.mk) { q.mk = 0 ; return(p - q) ; } for (rg int i = 1 ; i <= p.len ; ++ i) res.v[i] = p.v[i] + q.v[i] ; res.len = p.len ; for (rg int i = 1 ; i <= p.len + 1 ; ++ i) if (res.v[i] >= Base) res.v[i + 1] += res.v[i] / Base, res.v[i] %= Base ; for (rg int i = res.len + 10 ; i >= 0 ; -- i) if (res.v[i]) { res.len = i ; break ; } res.lent = (res.len - 1) * 8 + get_L(res.v[res.len]) ; return res ; } il Big_Num friend operator * (const Big_Num & A, const Big_Num & B){ Big_Num res ; res.reset() ; res.len = A.len + B.len ; for (rg int i = 1 ; i <= A.len ; ++ i) for (rg int j = 1 ; j <= B.len ; ++ j) res.v[i + j - 1] += A.v[i] * B.v[j] ; for (rg int i = 1 ; i <= res.len + 10 ; ++ i) res.v[i + 1] += res.v[i] / Base, res.v[i] %= Base ; res.v[0] = -1 ; for (rg int i = res.len + 10 ; i >= 0 ; -- i) if (res.v[i]) { res.len = i ; break ; } if (!res.len) res.len ++ ; res.lent = (res.len - 1) * 8 + get_L(res.v[res.len]) ; return res ; } il void div2() { for (rg int i = len ; i >= 1 ; -- i) v[i - 1] += (v[i] % 2ll) * Base, v[i] >>= 1 ; v[0] >>= 1 ; while(v[len] == 0) len -- ; lent = (len - 1) * 8 + get_L(v[len]) ; } il void mul2() { int r = 0 ; for (rg int i = 1 ; i <= len ; ++ i) { v[i] = v[i] * 2 + r, r = 0 ; if(v[i] >= Base) { r = v[i] / Base, v[i] %= Base ; if (i == len) len ++ ; } } lent = (len - 1) * 8 + get_L(v[len]) ; } Big_Num friend gcd(Big_Num A, Big_Num B){ int cnt2 = 0 ; while(!(A ^ B)){ if (A < B) swap(A, B) ; bool a = A.v[1] & 1, b = B.v[1] & 1 ; if (!a && !b) A.div2(), B.div2(), ++ cnt2 ; else if (!b) B.div2() ; else if (!a) A.div2() ; else A = A - B ; } Big_Num tmp, pmt ; tmp.set_v(2), pmt.set_v(1) ; while (cnt2){ if (cnt2 & 1) pmt = pmt * tmp ; tmp = tmp * tmp ; cnt2 >>= 1 ; } return (A = A * pmt) ; } } ; Big_Num g, t ; Big_Num l, r, mid, ans ; struct Frac{ Big_Num fz, fm ; il void reset(){ fz.reset() ; fm.reset() ; } il void reverse(){ Big_Num t = fz ; fz = fm, fm = t ; } il void div(){ g = gcd(fz, fm) ; r.reset() ; int lnr = fz.len - g.len ; l.reset() ; l.len = lnr ; l.v[l.len] = 1 ; r.len = lnr + 1 ; r.v[r.len] = 90000000 ; while (l <= r){ mid = (l + r) ; mid.div2() ; if (mid * g >= fz) ans = mid, r = mid - t ; else l = mid + t ; } fz = ans ; l.reset() ; lnr = fm.len - g.len ; l.reset() ; l.len = lnr ; l.v[l.len] = 1 ; r.len = lnr + 1 ; r.v[r.len] = 90000000 ; while (l <= r){ mid = (l + r) ; mid.div2() ; if (mid * g >= fm) ans = mid, r = mid - t ; else l = mid + t ; } fm = ans ; } il void out_put(){ fz.out_put() ; putchar('/') ; fm.out_put() ; puts("") ; } template <typename T> il void set_v(T son, T mum){ fz.set_v(son), fm.set_v(mum) ; } template <typename T> il void set_v(char *son, int Lson, char *mum, int Lmum){ fz.set_v(son, Lson) ; fm.set_v(mum, Lmum) ; } il Frac friend operator + (Frac A, Frac B){ Frac res ; res.reset() ; if (!A.fz.len && !A.fm.len) return B ; if (!B.fz.len && !B.fm.len) return A ; if (!(A.fm ^ B.fm)){ Big_Num p = A.fm, q = B.fm, o, s, t ; o = p * q ; s = q * A.fz ; t = p * B.fz ; A.fm = o ; B.fm = o ; A.fz = s ; B.fz = t ; } res.fm = A.fm ; res.fz = A.fz + B.fz ; return res ; } il Frac friend operator - (Frac A, Frac B){ Frac res ; res.reset() ; if (!(A.fm ^ B.fm)){ Big_Num p = A.fm, q = B.fm, o, s, t ; o = p * q ; s = q * A.fz ; t = p * B.fz ; A.fm = o ; B.fm = o ; A.fz = s ; B.fz = t ; } res.fm = A.fm ; res.fz = A.fz - B.fz ; return res ; } il Frac friend operator * (const Frac & A, const Frac & B){ Frac res ; res.reset() ; res.fm = A.fm * B.fm ; res.fz = A.fz * B.fz ; return res ; } il Frac friend operator ^ (const Frac & A, const Frac & B){ Frac res ; res.reset() ; res.fz = A.fz * B.fz ; res.fm = A.fm ; return res ; } il Frac friend operator & (const Frac & A, const Frac & B){ Frac res ; res.reset() ; res.fm = A.fm * B.fm ; res.fz = A.fz ; return res ; } } r1, r2, r3, r0 ; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ int f[N] ; int A, B ; Frac res ; char S[N] ; Frac Rp[N] ; Frac Pr[N] ; int base[N] ; int T, n, m ; int main(){ cin >> A >> B ; cin >> (S + 1) ; r0.set_v(1, B) ; r1.set_v(A, 1) ; Rp[0].set_v(1, 1) ; r2.set_v(B - A, 1) ; m = strlen(S + 1), Pr[m].set_v(1, 1) ; for (rg int i = 1 ; i <= m ; ++ i) base[i] = (bool)(S[i] == 'H') ; for (rg int j = m ; j >= 1 ; -- j) Pr[j - 1] = Pr[j] ^ (base[j] ? r1 : r2) ; for (rg int j = 1 ; j <= m ; ++ j) Rp[j] = Rp[j - 1] & r0 ; for (rg int i = 2, j = 0 ; i <= m ; ++ i){ while (j && base[j + 1] != base[i]) j = f[j] ; if (base[j + 1] == base[i]) ++ j ; f[i] = j ; } t.reset() ; t.set_v(1) ; r3 = Pr[0] * Rp[m] ; r3.reverse() ; int k = m ; while (m) res = res + Pr[m] * Rp[k - m] , m = f[m] ; res = res * r3 ; res.div() ; res.out_put() ; return 0 ; } ```