zoukankan      html  css  js  c++  java
  • LightOJ 1064 dp

    /********************
    
    LightOJ 1064
    
    Author:Cdegree
    
    ********************/
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <cctype>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <map>
    #include <algorithm>
    #include <iostream>
    #include <string>
    #include <set>
    #define X first
    #define Y second
    #define sqr(x) (x)*(x)
    #pragma comment(linker,"/STACK:102400000,102400000")
    using namespace std;
    const double PI = acos(-1.0);
    map<int, int>::iterator it;
    typedef long long LL ;
    template<typename T> void checkmin(T &x, T y) {x = min(x, y);}
    template<typename T> void checkmax(T &x, T y) {x = max(x, y);}
    
    #define DIGIT    4
    #define DEPTH    10000
    #define MAX     50
    typedef int bignum_t[MAX+1];
    
    int read(bignum_t a, istream& is = cin) {
        char buf[MAX*DIGIT+1], ch;
        int i, j;
        memset((void*)a, 0, sizeof(bignum_t));
        if(!(is >> buf))    return 0;
        for(a[0] = strlen(buf), i = a[0] / 2 - 1; i >= 0; i--)
            ch = buf[i], buf[i] = buf[a[0] - 1 - i], buf[a[0] - 1 - i] = ch;
        for(a[0] = (a[0] + DIGIT - 1) / DIGIT, j = strlen(buf); j < a[0]*DIGIT; buf[j++] = '0');
        for(i = 1; i <= a[0]; i++)
            for(a[i] = 0, j = 0; j < DIGIT; j++)
                a[i] = a[i] * 10 + buf[i*DIGIT-1-j] - '0';
        for(; !a[a[0]] && a[0] > 1; a[0]--);
        return 1;
    }
    
    void write(const bignum_t a, ostream& os = cout) {
        int i, j;
        for(os << a[i=a[0]], i--; i; i--)
            for(j = DEPTH / 10; j; j /= 10)
                os << a[i] / j % 10;
    }
    
    int comp(const bignum_t a, const bignum_t b) {
        int i;
        if(a[0] != b[0])
            return a[0] - b[0];
        for(i = a[0]; i; i--)
            if(a[i] != b[i])
                return a[i] - b[i];
        return 0;
    }
    
    int comp(const bignum_t a, const int b) {
        int c[12] = {1};
        for(c[1] = b; c[c[0]] >= DEPTH; c[c[0] + 1] = c[c[0]] / DEPTH, c[c[0]] %= DEPTH, c[0]++);
        return comp(a, c);
    }
    
    int comp(const bignum_t a, const int c, const int d, const bignum_t b) {
        int i, t = 0, O = -DEPTH * 2;
        if(b[0] - a[0] < d && c)
            return 1;
        for(i = b[0]; i > d; i--) {
            t = t * DEPTH + a[i-d] * c - b[i];
            if(t > 0) return 1;
            if(t < O) return 0;
        }
        for(i = d; i; i--) {
            t = t * DEPTH - b[i];
            if(t > 0) return 1;
            if(t < O) return 0;
        }
        return t > 0;
    }
    
    void add(bignum_t a, const bignum_t b) {
        int i;
        for(i = 1; i <= b[0]; i++)
            if((a[i] += b[i]) >= DEPTH)
                a[i] -= DEPTH, a[i+1]++;
        if(b[0] >= a[0])
            a[0] = b[0];
        else
            for(; a[i] >= DEPTH && i < a[0]; a[i] -= DEPTH, i++, a[i]++);
        a[0] += (a[a[0] + 1] > 0);
    }
    
    void add(bignum_t a, const int b) {
        int i = 1;
        for(a[1] += b; a[i] >= DEPTH && i < a[0]; a[i+1] += a[i] / DEPTH, a[i] %= DEPTH, i++);
        for(; a[a[0]] >= DEPTH; a[a[0] + 1] = a[a[0]] / DEPTH, a[a[0]] %= DEPTH, a[0]++);
    }
    
    void sub(bignum_t a, const bignum_t b) {
        int i;
        for(i = 1; i <= b[0]; i++)
            if((a[i] -= b[i]) < 0)
                a[i+1]--, a[i] += DEPTH;
        for(; a[i] < 0; a[i] += DEPTH, i++, a[i]--);
        for(; !a[a[0]] && a[0] > 1; a[0]--);
    }
    
    void sub(bignum_t a, const int b) {
        int i = 1;
        for(a[1] -= b; a[i] < 0; a[i+1] += (a[i] - DEPTH + 1) / DEPTH, a[i] -= (a[i] - DEPTH + 1) / DEPTH * DEPTH, i++);
        for(; !a[a[0]] && a[0] > 1; a[0]--);
    }
    
    void sub(bignum_t a, const bignum_t b, const int c, const int d) {
        int i, O = b[0] + d;
        for(i = 1 + d; i <= O; i++)
            if((a[i] -= b[i-d] * c) < 0)
                a[i+1] += (a[i] - DEPTH + 1) / DEPTH, a[i] -= (a[i] - DEPTH + 1) / DEPTH * DEPTH;
        for(; a[i] < 0; a[i+1] += (a[i] - DEPTH + 1) / DEPTH, a[i] -= (a[i] - DEPTH + 1) / DEPTH * DEPTH, i++);
        for(; !a[a[0]] && a[0] > 1; a[0]--);
    }
    
    void mul(bignum_t c, const bignum_t a, const bignum_t b) {
        int i, j;
        memset((void*)c, 0, sizeof(bignum_t));
        for(c[0] = a[0] + b[0] - 1, i = 1; i <= a[0]; i++)
            for(j = 1; j <= b[0]; j++)
                if((c[i+j-1] += a[i] * b[j]) >= DEPTH)
                    c[i+j] += c[i+j-1] / DEPTH, c[i+j-1] %= DEPTH;
        for(c[0] += (c[c[0] + 1] > 0); !c[c[0]] && c[0] > 1; c[0]--);
    }
    
    void mul(bignum_t a, const int b) {
        int i;
        for(a[1] *= b, i = 2; i <= a[0]; i++) {
            a[i] *= b;
            if(a[i-1] >= DEPTH)
                a[i] += a[i-1] / DEPTH, a[i-1] %= DEPTH;
        }
        for(; a[a[0]] >= DEPTH; a[a[0] + 1] = a[a[0]] / DEPTH, a[a[0]] %= DEPTH, a[0]++);
        for(; !a[a[0]] && a[0] > 1; a[0]--);
    }
    
    void mul(bignum_t b, const bignum_t a, const int c, const int d) {
        int i;
        memset((void*)b, 0, sizeof(bignum_t));
        for(b[0] = a[0] + d, i = d + 1; i <= b[0]; i++)
            if((b[i] += a[i-d] * c) >= DEPTH)
                b[i+1] += b[i] / DEPTH, b[i] %= DEPTH;
        for(; b[b[0] + 1]; b[0]++, b[b[0] + 1] = b[b[0]] / DEPTH, b[b[0]] %= DEPTH);
        for(; !b[b[0]] && b[0] > 1; b[0]--);
    }
    
    void div(bignum_t c, bignum_t a, const bignum_t b) {
        int h, l, m, i;
        memset((void*)c, 0, sizeof(bignum_t));
        c[0] = (b[0] < a[0] + 1) ? (a[0] - b[0] + 2) : 1;
        for(i = c[0]; i; sub(a, b, c[i] = m, i - 1), i--)
            for(h = DEPTH - 1, l = 0, m = (h + l + 1) >> 1; h > l; m = (h + l + 1) >> 1)
                if(comp(b, m, i - 1, a)) h = m - 1;
                else l = m;
        for(; !c[c[0]] && c[0] > 1; c[0]--);
        c[0] = c[0] > 1 ? c[0] : 1;
    }
    
    void div(bignum_t a, const int b, int& c) {
        int i;
        for(c = 0, i = a[0]; i; c = c*DEPTH + a[i], a[i] = c / b, c %= b, i--);
        for(; !a[a[0]] && a[0] > 1; a[0]--);
    }
    
    void sqrt(bignum_t b, bignum_t a) {
        int h, l, m, i;
        memset((void*)b, 0, sizeof(bignum_t));
        for(i = b[0] = (a[0] + 1) >> 1; i; sub(a, b, m, i - 1), b[i] += m, i--)
            for(h = DEPTH - 1, l = 0, b[i] = m = (h + l + 1) >> 1; h > l; b[i] = m = (h + l + 1) >> 1)
                if(comp(b, m, i - 1, a)) h = m - 1;
                else l = m;
        for(; !b[b[0]] && b[0] > 1; b[0]--);
        for(i = 1; i <= b[0]; b[i++] >>= 1);
    }
    
    int length(const bignum_t a) {
        int t, ret;
        for(ret = (a[0] - 1) * DIGIT, t = a[a[0]]; t; t /= 10, ret++);
        return ret > 0 ? ret : 1;
    }
    
    int digit(const bignum_t a, const int b) {
        int i, ret;
        for(ret = a[(b-1)/DIGIT+1], i = (b - 1) % DIGIT; i; ret /= 10, i--);
        return ret % 10;
    }
    
    int zeronum(const bignum_t a) {
        int ret, t;
        for(ret = 0; !a[ret+1]; ret++);
        for(t = a[ret+1], ret *= DIGIT; !(t % 10); t /= 10, ret++);
        return ret;
    }
    
    void comp(int* a, const int l, const int h, const int d) {
        int i, j, t;
        for(i = l; i <= h; i++)
            for(t = i, j = 2; t > 1; j++)
                while(!(t % j))
                    a[j] += d, t /= j;
    }
    
    void convert(int* a, const int h, bignum_t b) {
        int i, j, t = 1;
        memset(b, 0, sizeof(bignum_t));
        for(b[0] = b[1] = 1, i = 2; i <= h; i++)
            if(a[i])
                for(j = a[i]; j; t *= i, j--)
                    if(t * i > DEPTH)
                        mul(b, t), t = 1;
        mul(b, t);
    }
    
    void combination(bignum_t a, int m, int n) {
        int* t = new int[m+1];
        memset((void*)t, 0, sizeof(int)*(m + 1));
        comp(t, n + 1, m, 1);
        comp(t, 2, m - n, -1);
        convert(t, m, a);
        delete []t;
    }
    
    void permutation(bignum_t a, int m, int n) {
        int i, t = 1;
        memset(a, 0, sizeof(bignum_t));
        a[0] = a[1] = 1;
        for(i = m - n + 1; i <= m; t *= i++)
            if(t * i > DEPTH)
                mul(a, t), t = 1;
        mul(a, t);
    }
    
    #define SGN(x) ((x)>0?1:((x)<0?-1:0))
    #define ABS(x) ((x)>0?(x):-(x))
    
    int read(bignum_t a, int &sgn, istream& is = cin) {
        char str[MAX*DIGIT+2], ch, *buf;
        int i, j;
        memset((void*)a, 0, sizeof(bignum_t));
        if(!(is >> str)) return 0;
        buf = str, sgn = 1;
        if(*buf == '-') sgn = -1, buf++;
        for(a[0] = strlen(buf), i = a[0] / 2 - 1; i >= 0; i--)
            ch = buf[i], buf[i] = buf[a[0] - 1 - i], buf[a[0] - 1 - i] = ch;
        for(a[0] = (a[0] + DIGIT - 1) / DIGIT, j = strlen(buf); j < a[0]*DIGIT; buf[j++] = '0');
        for(i = 1; i <= a[0]; i++)
            for(a[i] = 0, j = 0; j < DIGIT; j++)
                a[i] = a[i] * 10 + buf[i*DIGIT-1-j] - '0';
        for(; !a[a[0]] && a[0] > 1; a[0]--);
        if(a[0] == 1 && !a[1]) sgn = 0;
        return 1;
    }
    
    struct bignum {
        bignum_t num;
        int sgn;
    public:
        inline bignum() {memset(num, 0, sizeof(bignum_t)); num[0] = 1; sgn = 0;}
        inline int operator!() {return num[0] == 1 && !num[1];}
        inline bignum& operator=(const bignum& a) {memcpy(num, a.num, sizeof(bignum_t)); sgn = a.sgn; return *this;}
        inline bignum& operator=(const int a) {memset(num, 0, sizeof(bignum_t)); num[0] = 1; sgn = SGN(a); add(num, sgn * a); return *this;};
        inline bignum& operator+=(const bignum& a) {
            if(sgn == a.sgn)add(num, a.num); else if(sgn && a.sgn) {
                int ret = comp(num, a.num); if(ret > 0)sub(num, a.num); else if(ret < 0) {
                    bignum_t t;
                    memcpy(t, num, sizeof(bignum_t)); memcpy(num, a.num, sizeof(bignum_t)); sub(num, t); sgn = a.sgn;
                }
                else memset(num, 0, sizeof(bignum_t)), num[0] = 1, sgn = 0;
            }
            else if(!sgn)memcpy(num, a.num, sizeof(bignum_t)), sgn = a.sgn; return *this;
        }
        inline bignum& operator+=(const int a) {
            if(sgn * a > 0)add(num, ABS(a)); else if(sgn && a) {
                int ret = comp(num, ABS(a)); if(ret > 0)sub(num, ABS(a)); else if(ret < 0) {
                    bignum_t t;
                    memcpy(t, num, sizeof(bignum_t)); memset(num, 0, sizeof(bignum_t)); num[0] = 1; add(num, ABS(a)); sgn = -sgn; sub(num, t);
                }
                else memset(num, 0, sizeof(bignum_t)), num[0] = 1, sgn = 0;
            }
            else if(!sgn)sgn = SGN(a), add(num, ABS(a)); return *this;
        }
        inline bignum operator+(const bignum& a) {bignum ret; memcpy(ret.num, num, sizeof(bignum_t)); ret.sgn = sgn; ret += a; return ret;}
        inline bignum operator+(const int a) {bignum ret; memcpy(ret.num, num, sizeof(bignum_t)); ret.sgn = sgn; ret += a; return ret;}
        inline bignum& operator-=(const bignum& a) {
            if(sgn * a.sgn < 0)add(num, a.num); else if(sgn && a.sgn) {
                int ret = comp(num, a.num); if(ret > 0)sub(num, a.num); else if(ret < 0) {
                    bignum_t t;
                    memcpy(t, num, sizeof(bignum_t)); memcpy(num, a.num, sizeof(bignum_t)); sub(num, t); sgn = -sgn;
                }
                else memset(num, 0, sizeof(bignum_t)), num[0] = 1, sgn = 0;
            }
            else if(!sgn)add(num, a.num), sgn = -a.sgn; return *this;
        }
        inline bignum& operator-=(const int a) {
            if(sgn * a < 0)add(num, ABS(a)); else if(sgn && a) {
                int ret = comp(num, ABS(a)); if(ret > 0)sub(num, ABS(a)); else if(ret < 0) {
                    bignum_t t;
                    memcpy(t, num, sizeof(bignum_t)); memset(num, 0, sizeof(bignum_t)); num[0] = 1; add(num, ABS(a)); sub(num, t); sgn = -sgn;
                }
                else memset(num, 0, sizeof(bignum_t)), num[0] = 1, sgn = 0;
            }
            else if(!sgn)sgn = -SGN(a), add(num, ABS(a)); return *this;
        }
        inline bignum operator-(const bignum& a) {bignum ret; memcpy(ret.num, num, sizeof(bignum_t)); ret.sgn = sgn; ret -= a; return ret;}
        inline bignum operator-(const int a) {bignum ret; memcpy(ret.num, num, sizeof(bignum_t)); ret.sgn = sgn; ret -= a; return ret;}
        inline bignum& operator*=(const bignum& a) {bignum_t t; mul(t, num, a.num); memcpy(num, t, sizeof(bignum_t)); sgn *= a.sgn; return *this;}
        inline bignum& operator*=(const int a) {mul(num, ABS(a)); sgn *= SGN(a); return *this;}
        inline bignum operator*(const bignum& a) {bignum ret; mul(ret.num, num, a.num); ret.sgn = sgn * a.sgn; return ret;}
        inline bignum operator*(const int a) {bignum ret; memcpy(ret.num, num, sizeof(bignum_t)); mul(ret.num, ABS(a)); ret.sgn = sgn * SGN(a); return ret;}
        inline bignum& operator/=(const bignum& a) {bignum_t t; div(t, num, a.num); memcpy(num, t, sizeof(bignum_t)); sgn = (num[0] == 1 && !num[1]) ? 0 : sgn * a.sgn; return *this;}
        inline bignum& operator/=(const int a) {int t; div(num, ABS(a), t); sgn = (num[0] == 1 && !num[1]) ? 0 : sgn * SGN(a); return *this;}
        inline bignum operator/(const bignum& a) {bignum ret; bignum_t t; memcpy(t, num, sizeof(bignum_t)); div(ret.num, t, a.num); ret.sgn = (ret.num[0] == 1 && !ret.num[1]) ? 0 : sgn * a.sgn; return ret;}
        inline bignum operator/(const int a) {bignum ret; int t; memcpy(ret.num, num, sizeof(bignum_t)); div(ret.num, ABS(a), t); ret.sgn = (ret.num[0] == 1 && !ret.num[1]) ? 0 : sgn * SGN(a); return ret;}
        inline bignum& operator%=(const bignum& a) {bignum_t t; div(t, num, a.num); if(num[0] == 1 && !num[1])sgn = 0; return *this;}
        inline int operator%=(const int a) {int t; div(num, ABS(a), t); memset(num, 0, sizeof(bignum_t)); num[0] = 1; add(num, t); return t;}
        inline bignum operator%(const bignum& a) {bignum ret; bignum_t t; memcpy(ret.num, num, sizeof(bignum_t)); div(t, ret.num, a.num); ret.sgn = (ret.num[0] == 1 && !ret.num[1]) ? 0 : sgn; return ret;}
        inline int operator%(const int a) {bignum ret; int t; memcpy(ret.num, num, sizeof(bignum_t)); div(ret.num, ABS(a), t); memset(ret.num, 0, sizeof(bignum_t)); ret.num[0] = 1; add(ret.num, t); return t;}
        inline bignum& operator++() {*this += 1; return *this;}
        inline bignum& operator--() {*this -= 1; return *this;};
        inline int operator>(const bignum& a) {return sgn > 0 ? (a.sgn > 0 ? comp(num, a.num) > 0 : 1) : (sgn < 0 ? (a.sgn < 0 ? comp(num, a.num) < 0 : 0) : a.sgn < 0);}
        inline int operator>(const int a) {return sgn > 0 ? (a > 0 ? comp(num, a) > 0 : 1) : (sgn < 0 ? (a < 0 ? comp(num, -a) < 0 : 0) : a < 0);}
        inline int operator>=(const bignum& a) {return sgn > 0 ? (a.sgn > 0 ? comp(num, a.num) >= 0 : 1) : (sgn < 0 ? (a.sgn < 0 ? comp(num, a.num) <= 0 : 0) : a.sgn <= 0);}
        inline int operator>=(const int a) {return sgn > 0 ? (a > 0 ? comp(num, a) >= 0 : 1) : (sgn < 0 ? (a < 0 ? comp(num, -a) <= 0 : 0) : a <= 0);}
        inline int operator<(const bignum& a) {return sgn < 0 ? (a.sgn < 0 ? comp(num, a.num) > 0 : 1) : (sgn > 0 ? (a.sgn > 0 ? comp(num, a.num)<0 : 0) : a.sgn>0);}
        inline int operator<(const int a) {return sgn < 0 ? (a < 0 ? comp(num, -a) > 0 : 1) : (sgn > 0 ? (a > 0 ? comp(num, a)<0 : 0) : a>0);}
        inline int operator<=(const bignum& a) {return sgn < 0 ? (a.sgn < 0 ? comp(num, a.num) >= 0 : 1) : (sgn > 0 ? (a.sgn > 0 ? comp(num, a.num) <= 0 : 0) : a.sgn >= 0);}
        inline int operator<=(const int a) {return sgn < 0 ? (a < 0 ? comp(num, -a) >= 0 : 1) : (sgn > 0 ? (a > 0 ? comp(num, a) <= 0 : 0) : a >= 0);}
        inline int operator==(const bignum& a) {return (sgn == a.sgn) ? !comp(num, a.num) : 0;}
        inline int operator==(const int a) {return (sgn*a >= 0) ? !comp(num, ABS(a)) : 0;}
        inline int operator!=(const bignum& a) {return (sgn == a.sgn) ? comp(num, a.num) : 1;}
        inline int operator!=(const int a) {return (sgn*a >= 0) ? comp(num, ABS(a)) : 1;}
        inline int operator[](const int a) {return digit(num, a);}
        friend inline istream& operator>>(istream& is, bignum& a) {read(a.num, a.sgn, is); return is;}
        friend inline ostream& operator<<(ostream& os, const bignum& a) {if(a.sgn < 0)os << '-'; write(a.num, os); return os;}
        friend inline bignum sqrt(const bignum& a) {bignum ret; bignum_t t; memcpy(t, a.num, sizeof(bignum_t)); sqrt(ret.num, t); ret.sgn = ret.num[0] != 1 || ret.num[1]; return ret;}
        friend inline bignum sqrt(const bignum& a, bignum& b) {bignum ret; memcpy(b.num, a.num, sizeof(bignum_t)); sqrt(ret.num, b.num); ret.sgn = ret.num[0] != 1 || ret.num[1]; b.sgn = b.num[0] != 1 || ret.num[1]; return ret;}
        inline int length() {return ::length(num);}
        inline int zeronum() {return ::zeronum(num);}
        inline bignum C(const int m, const int n) {combination(num, m, n); sgn = 1; return *this;}
        inline bignum P(const int m, const int n) {permutation(num, m, n); sgn = 1; return *this;}
    };
    
    
    bignum dp[27][7][155];
    
    bignum Power(bignum x, int n) {
        bignum ret;
        ret = 1;
        while(n--) {
            ret *= x;
        }
        return ret;
    }
    
    bignum gcd(bignum a, bignum b) {
        return b == 0 ? a : gcd(b, a % b);
    }
    
    
    int main() {
        int T;
        scanf("%d", &T);
        int n, x;
        for(int t = 1; t <= T; ++t) {
            cin >> n >> x;
            bignum dic;
            dic = 6;
            bignum fm = Power(dic, n);
            for(int i = 1; i <= 6; ++i) {
                dp[1][i][i] = 1;
            }
            for(int i = 2; i <= n; ++i) {
                for(int j = 1; j <= 6; ++j) {
                    for(int k = 0; k <= 150; ++k) {
                        dp[i][j][k] = 0;
                        for(int p = 1; p <= 6; ++p) {
                            if(k - j >= 0)dp[i][j][k] += dp[i-1][p][k-j];
                        }
                    }
                }
            }
            bignum fz;
            fz=0;
            for(int i = 1; i <= 6; ++i) {
                for(int j = x; j <= 150; ++j) {
                    fz += dp[n][i][j];
                }
            }
            bignum g = gcd(fz,fm);
            fz /= g;
            fm /= g;
            printf("Case %d: ",t);
            if(fm==1)cout<<fz<<endl;
            else cout<<fz<<"/"<<fm<<endl;
        }
        return 0;
    }
  • 相关阅读:
    Oracle函数如何把符串装换为小写的格式
    Oralce中的synonym同义词
    JS中getYear()的兼容问题
    How to do SSH Tunneling (Port Forwarding)
    所谓深度链接(Deep linking)
    upload size of asp.net
    发一个自动刷网站PV流量的小工具
    解决Visual Studio 2008 下,打开.dbml(LINQ) 文件时,提示"The operation could not be completed." 的问题。
    在资源管理器中使鼠标右键增加一个命令,运行cmd,同时使得当前路径为资源管理器当前的目录
    使用SQL语句获取Sql Server数据库的版本
  • 原文地址:https://www.cnblogs.com/cxw199204/p/3349576.html
Copyright © 2011-2022 走看看