码迷,mamicode.com
首页 > 其他好文 > 详细

【模板】常用

时间:2020-04-09 12:15:38      阅读:61      评论:0      收藏:0      [点我收藏+]

标签:double   gauss   nsf   pow   大整数   template   min   动态规划   down   

1 IO 优化

#define ID isdigit(c = *next++)
#define IS isspace(c = *next++)

struct Istream {
    int size; char *next, buf[20030731];
    Istream & init(FILE *f = stdin) {fread(buf, 1, sizeof buf, f); next = buf; return *this;}
    Istream & operator >> (int &x) {
        int c; x = 0;
        for (; !ID; ) if (!~c) return *this;
        for (x = c & 15; ID; x = x * 10 + (c & 15));
        return *this;
    }
    Istream & operator >> (char *x) {
        int c;
        for (; IS; ) if (!~c) return *this;
        for (*x++ = c; !IS; *x++ = c) if (!~c) break;
        return *x = 0, *this;
    }
    char get() {return *next++;}
} cin;

struct Ostream {
    char *next, buf[20030731], _buf[34];
    Ostream () {next = buf;}
    void flush(FILE *f = stdout) {fwrite(buf, 1, next - buf, f); next = buf;}
    Ostream & operator << (int x) {
        if (!x) return put(48), *this;
        int i;
        for (i = 0; x; x /= 10) _buf[++i] = x % 10 | 48;
        for (; i; --i) put(_buf[i]);
        return *this;
    }
    Ostream & operator << (char c) {return put(c), *this;}
    Ostream & operator << (const char *s) {for (char *p = (char*)s; *p; ++p) put(*p); return *this;}
    void put(char c) {*next++ = c;}
} cout;

 

2 动态规划的转移

inline void up(int &x, const int y) {x < y ? x = y : 0;}
inline void down(int &x, const int y) {x > y ? x = y : 0;}
inline int min(const int x, const int y) {return x < y ? x : y;}
inline int max(const int x, const int y) {return x < y ? y : x;}
inline int & reduce(int &x) {return x += x >> 31 & mod;}
inline void add(int &x, const int y) {x += y - mod, x += x >> 31 & mod;}
inline void sub(int &x, const int y) {x -= y, x += x >> 31 & mod;}
inline int & half(int &x) {return x = (x >> 1) + (-(x & 1) & half_mod);}
inline int & neg(int &x) {return x = (!x - 1) & (mod - x);}

// another ver.
inline bool up(int &x, const int y) {return x < y ? x = y, 1 : 0;}
inline bool down(int &x, const int y) {return x > y ? x = y, 1 : 0;}
inline int & add(int &x, const int y) {return x += y - mod, x += x >> 31 & mod;}
inline int & sub(int &x, const int y) {return x -= y, x += x >> 31 & mod;}

// templated ver.
#define templated template <typename T>
inline bool up(T &x, const T y) {return x < y ? x = y, 1 : 0;}
inline bool down(T &x, const T y) {return x > y ? x = y, 1 : 0;}
inline T min(const T x, const T y) {return x < y ? x : y;}
inline T max(const T x, const T y) {return x < y ? y : x;}

 

3 乘模函数 (64 bit 大整数相乘取模)

inline ll MulMod(ll a, ll b, ll m){
    ll t = (a * b - (ll)((ld)a * b / m) * m) % m;
    return t + (t >> 63 & m);
}

 

4 ST 

void build_st_table() {
    int *f, *g = *st, i, j, k = cnt;
    for (j = 0; 1 << j + 1 <= cnt; ++j) {
        f = g; g = st[j + 1]; k -= 1 << j;
        for (i = 0; i < k; ++i)
            g[i] = min(f[i], f[i + (1 << j)]);
    }
}

inline int range(int L, int R) { // [L, R)
    int D = R - L, c = lg2(D);
    return min(st[c][L], st[c][R - (1 << c)]);
}

 

5 离散化

namespace DC {
    int F[N]; pr D[N];

    int Discretize(int n) {
        int i, cnt = 0;
        std::sort(D, D + n);
        for (i = 0; i < n; ++i)
            F[D[i].second] = (i && D[i].first == D[i - 1].first ? cnt - 1 : (D[cnt] = D[i], cnt++));
        return cnt;
    }
}

 

6 Hash Map

class hash_map{
public:
    static const int HASH_MAX = 0xffffff, N = 8000000;
    int cnt, first[HASH_MAX + 2], next[N]; data z[N];
    inline int getHash(int key) {return (key ^ key << 3 ^ key >> 2) & HASH_MAX;}

    void clear() {for(; cnt > 0; --cnt) first[z[cnt].hash] = 0;}

    data * find(int key, bool inserted){
        int x = getHash(key), i;
        for(i = first[x]; i; i = next[i]) if(z[i].key == key) return z + i;
        if(!inserted) return NULL;
        z[++cnt] = data(key, 0, x); next[cnt] = first[x]; first[x] = cnt;
        return z + cnt;
    }
};

 

7 快速 Fourier 变换 (Fast Fourier Transform)

// ‘Fast Number Theory Transform‘ is in memos/12.html.
namespace Poly {
    typedef std::complex <double> C;

    const int N = 530000;
    int l, n, rev[N];
    C x[N], y[N], B1[N], B2[N], B3[N];

    void FFT_init(int len) {
        if (l == len) return; n = 1 << (l = len);
        int i; double angle = M_PI;
        for (i = l - 1; i >= 0; angle *= .5, --i) x[1 << i] = C(cos(angle), sin(angle));
        for (i = 3; i < n; ++i) if (i & (i - 1)) x[i] = x[i & -i] * x[i ^ (i & -i)];
        *x = C(1.), *rev = 0;
        for (i = 1; i < n; ++i) rev[i] = rev[i >> 1] >> 1 | (i & 1) << (l - 1);
    }

    void DFT(C *d, C *t) {
        int i, len = 1, delta = n; C *j, *k, R;
        for (i = 0; i < n; ++i) t[rev[i]] = d[i];
        for (i = 0; i < l; ++i) {
            delta >>= 1;
            for (k = x, j = y; j < y + len; k += delta, ++j) *j = *k;
            for (j = t; j < t + n; j += len << 1)
                for (k = j; k < j + len; ++k)
                    R = y[k - j] * k[len], k[len] = *k - R, *k += R;
            len <<= 1;
        }
    }

    void Mul(int degA, int degB, double *a, double *b, double *c) {
        if (!(degA || degB)) {*c = *a * *b; return;}
        FFT_init(lg2(degA + degB) + 1);
        int i; double iv = 1.0 / n;
        for (i = 0; i <= degA; ++i) B1[i] = C(a[i]); std::fill(B1 + i, B1 + n, C());
        for (i = 0; i <= degB; ++i) B2[i] = C(b[i]); std::fill(B2 + i, B2 + n, C());
        DFT(B1, B3), DFT(B2, B1);
        for (i = 0; i < n; ++i) B1[i] *= B3[i];
        DFT(B1, B3), std::reverse(B3 + 1, B3 + n);
        for (i = 0; i <= degA + degB; ++i) c[i] = B3[i].real() * iv;
    }
}

 

8 Gauss 消元法


 

// Gauss elimination with type ‘double‘
struct LnEqn{
    int sz;
    double **m, *b;
    LnEqn (): sz(0) {m = NULL; b = NULL;}
    void resize(int size){
        sz = size; m = new double *[sz];
        for(int i = 0; i < sz; i++){
            m[i] = new double[sz];
            memset(m[i], 0, sz << 3);
        }
        b = new double[sz];
        memset(b, 0, sz << 3);
    }
    ~LnEqn (){
        if(m) {for(int i = 0; i < sz; i++) delete [] (m[i]); delete [] (m);}
        if(b) delete [] (b);
    }
    bool solve(){
        int i, j, k, maxi; double coe;
        for(k = 0; k < sz; k++){
            maxi = k;
            for(i = k + 1; i < sz; i++)
                if(fabs(m[i][k]) > fabs(m[maxi][k]))
                    maxi = i;
            if(fabs(m[maxi][k]) < 1e-8) return false;
            if(maxi != k){
                swap(m[maxi], m[k]);
                swap(b[maxi], b[k]);
            }
            coe = 1.0 / m[k][k];
            for(j = 0; j < sz; j++)
                m[k][j] *= coe;
            m[k][k] = 1.0;
            b[k] *= coe;
            for(i = 0; i < sz; i++){
                if(i == k) continue;
                coe = m[i][k];
                for(j = 0; j < sz; j++)
                    m[i][j] -= coe * m[k][j];
                m[i][k] = 0.0;
                b[i] -= coe * b[k];
            }
        }
        return true;
    }
};

 

9 线性规划 (x? ≥ 0, b? ≥ 0)

const double eps = 1e-8;

int id[N + E];

double m[E][N], b[E], *c = m[0], ans[N + E];

void pivot(int toFree, int toBasic); // basic(1,m) -> free, free(1,n) -> basic

void pivot(int r, int c){
    int i, j; double coe = 1.0 / m[r][c];
    swap(id[n + r], id[c]);
    m[r][c] = 1.0;
    for(j = 1; j <= n; ++j)
        m[r][j] *= coe;
    b[r] *= coe;
    for(i = 0; i <= e; ++i){
        if(i == r) continue;
        coe = m[i][c]; m[i][c] = 0.0;
        for(j = 1; j <= n; ++j)
            m[i][j] -= coe * m[r][j];
        b[i] -= coe * b[r];
    }
}

bool simplex(){
    int i, j, basic, free; double G;
    for(; ; ){
        basic = free = 0; G = INFINITY;
        for(i = 1; i <= n; ++i) // free (nonbasic) variable
            if(c[i] > c[free]) free = i;
        if(!free) return true;
        for(j = 1; j <= e; ++j) // basic variable
            if(m[j][free] > eps && b[j] < G * m[j][free]){
                G = b[j] / m[j][free]; basic = j;
            }
        if(!basic) return puts("Unbounded"), false;
        pivot(basic, free);
    }
}

// initialize :
for(j = 1; j <= n + e; ++j) id[j] = j;
c[0] = eps;

// output:
if(simplex()){
    printf("%.8lg\n", -*b);
    for(i = 1; i <= e; ++i) ans[id[n + i]] = b[i];
    for(j = 1; j <= n; ++j) printf("%.8lg%c", ans[j], j == n ? 10 : 32);
}

 

10 Gauss 消元求行列式 (模意义)

int gauss(int n) {
    int i, j, k, det = 1; ll coe;
    static int *m[N];
    for (i = 0; i < n; ++i) m[i] = mat[i];
    for (i = 0; i < n; ++i) {
        for (j = i; j < n && !m[j][i]; ++j);
        if (j == n) return 0;
        if (i != j) det = mod - det, std::swap(m[i], m[j]);
        det = (ll)det * m[i][i] % mod;
        coe = PowerMod(m[i][i], mod - 2);
        for (j = 0; j < n; ++j) m[i][j] = m[i][j] * coe % mod;
        for (k = i + 1; k < n; ++k)
            for (coe = mod - m[k][i], j = i; j < n; ++j) m[k][j] = (m[k][j] + coe * m[i][j]) % mod;
    }
    return det;
}

 

【模板】常用

标签:double   gauss   nsf   pow   大整数   template   min   动态规划   down   

原文地址:https://www.cnblogs.com/lau1997/p/12665852.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!