• 模板复习【updating】


    马上就要noi了……可能滚粗已经稳了……但是还是要复习模板啊

    LCT: bzoj2049 1A 7min

    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int M = 5e5 + 10;
    const int mod = 1e9+7;
    
    struct LCT {
        int ch[M][2], fa[M], sz[M]; bool rev[M];
        # define ls ch[x][0]
        # define rs ch[x][1]
        inline void up(int x) {
            if(!x) return ;
            sz[x] = 1 + sz[ls] + sz[rs];
        }
        inline void pushrev(int x) {
            if(!x) return ;
            rev[x] ^= 1;
            swap(ch[x][0], ch[x][1]);
        }
        inline void down(int x) {
            if(!x) return ;
            if(rev[x]) {
                pushrev(ls);
                pushrev(rs);
                rev[x] = 0;
            }
        }
        # undef ls 
        # undef rs
        inline bool isrt(int x) {
            return ch[fa[x]][0] != x && ch[fa[x]][1] != x;
        }
        inline void rotate(int x) {
            int y = fa[x], z = fa[y], ls = ch[y][1] == x, rs = ls^1;
            if(!isrt(y)) ch[z][ch[z][1] == y] = x;
            fa[ch[x][rs]] = y; fa[y] = x, fa[x] = z;
            ch[y][ls] = ch[x][rs]; ch[x][rs] = y;
            up(y); up(x);
        }
        int st[M];
        inline void splay(int x) {
            int stn = 0, tx = x;
            while(!isrt(tx)) st[++stn] = tx, tx = fa[tx];
            st[++stn] = tx;
            for (int i=stn; i; --i) down(st[i]);
            while(!isrt(x)) {
                int y = fa[x], z = fa[y];
                if(!isrt(y)) {
                    if((ch[z][0] == y) ^ (ch[y][0] == x)) rotate(x);
                    else rotate(y);
                }
                rotate(x);
            }
        }
        inline int access(int x) {
            int t = 0;
            for (; x; t=x, x=fa[x]) {
                splay(x);
                ch[x][1] = t;
                up(x);
            }
            return t;
        }
        inline void makeroot(int x) {
            access(x); splay(x); pushrev(x);
        }
        inline int find(int x) {
            access(x); splay(x);
            while(ch[x][0]) x = ch[x][0];
            return x;
        }
        inline void link(int x, int y) {
            makeroot(x); fa[x] = y;
        }
        inline void cut(int x, int y) {
            makeroot(x); access(y); splay(y); ch[y][0] = fa[x] = 0; up(y);
        }
    }T;
    
    int n, Q, x, y;
    
    int main() {
        static char op[23];
        cin >> n >> Q;
        for (int i=1; i<=n; ++i) {
            T.ch[i][0] = T.ch[i][1] = T.fa[i] = 0;
            T.sz[i] = 1; T.rev[i] = 0;
        }
        while(Q--) {
            scanf("%s%d%d", op, &x, &y);
            if(op[0] == 'C') T.link(x, y);
            else if(op[0] == 'D') T.cut(x, y);
            else puts(T.find(x) == T.find(y) ? "Yes" : "No");
        }
        return 0;
    }
    View Code

    dsu on tree: bzoj4756 1A 10min

    # include <vector>
    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int N = 1e5 + 10;
    const int mod = 1e9+7;
    
    int n, a[N];
    vector<int> ps;
    int head[N], nxt[N], to[N], tot = 0;
    inline void add(int u, int v) {
        ++tot; nxt[tot] = head[u]; head[u] = tot; to[tot] = v;
    }
    
    struct BIT {
        int n, c[N];
        # define lb(x) (x & (-x))
        inline void set(int _n) {
            n = _n;
            memset(c, 0, sizeof c);
        }
        inline void edt(int x, int d) {
            for (; x<=n; x+=lb(x)) c[x] += d;
        }
        inline int sum(int x) {
            int ret = 0;
            for (; x; x-=lb(x)) ret += c[x];
            return ret;
        }
        inline int sum(int x, int y) {
            if(x > y) return 0;
            return sum(y) - sum(x-1);
        }
        # undef lb
    }T;
    
    int sz[N], mx[N];
    inline void dfs(int x) {
        sz[x] = 1; mx[x] = 0;
        for (int i=head[x]; i; i=nxt[i]) {
            dfs(to[i]);
            sz[x] += sz[to[i]];
            if(mx[x] == 0 || sz[to[i]] > sz[mx[x]]) mx[x] = to[i];
        }
    }
    
    int ans[N], big[N];
    
    inline void count(int x, int p) {
        T.edt(a[x], p);
        for (int i=head[x]; i; i=nxt[i]) 
            if(!big[to[i]]) count(to[i], p);
    }
    
    inline void dsu(int x, bool kep = 0) {
        int son = mx[x];
        for (int i=head[x]; i; i=nxt[i]) 
            if(to[i] != son) dsu(to[i], 0);
        if(son) big[son] = 1, dsu(son, 1);
        count(x, 1);    
        ans[x] = T.sum(a[x] + 1, n);
        if(son) big[son] = 0;
        if(!kep) count(x, -1);
    }
    
    int main() {
        cin >> n; T.set(n);
        for (int i=1; i<=n; ++i) {
            scanf("%d", a+i);
            ps.push_back(a[i]);
        }
        sort(ps.begin(), ps.end());
        ps.erase(unique(ps.begin(), ps.end()), ps.end());
        for (int i=1; i<=n; ++i) a[i] = lower_bound(ps.begin(), ps.end(), a[i]) - ps.begin() + 1;
        for (int i=2, par; i<=n; ++i) {
            scanf("%d", &par);
            add(par, i);
        }
        dfs(1);
        dsu(1);
        for (int i=1; i<=n; ++i) printf("%d
    ", ans[i]);
        return 0;
    }
    
          
    View Code

    线段树合并: bzoj4756 2A 13min

    warning: 需要注意节点数量为$O(nlogn)$。

    # include <vector>
    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int N = 1e5 + 10, SN = 262144 * 20 + 5;
    const int mod = 1e9+7;
    
    int n, a[N];
    vector<int> ps;
    int head[N], nxt[N], to[N], tot = 0;
    inline void add(int u, int v) {
        ++tot; nxt[tot] = head[u]; head[u] = tot; to[tot] = v;
    }
    
    int rt[N];
    struct SMT {
        int siz;
        int s[SN], ch[SN][2];
        # define ls ch[x][0]
        # define rs ch[x][1]
        inline void set() {
            siz = 0;
            memset(ch, 0, sizeof ch);
            memset(s, 0, sizeof s);
        }
        inline void up(int x) {
            if(!x) return;
            s[x] = s[ls] + s[rs];
        }
        inline void edt(int &x, int l, int r, int ps, int d) {
            if(!x) x = ++siz;
            if(l == r) {
                s[x] = 1;
                return;
            }
            int mid = l+r>>1;
            if(ps <= mid) edt(ls, l, mid, ps, d);
            else edt(rs, mid+1, r, ps, d);
            up(x);
        }
        inline int sum(int x, int l, int r, int L, int R) {
            if(!x || L>R) return 0;
            if(L <= l && r <= R) return s[x];
            int mid = l+r>>1, ret = 0;
            if(L <= mid) ret += sum(ls, l, mid, L, R);
            if(R > mid) ret += sum(rs, mid+1, r, L, R);
            return ret;
        }
        inline int merge(int x, int y, int l, int r) {
            if(!x || !y) return x+y;
            if(l == r) {
                s[x] += s[y];
                return x;
            }
            int mid = l+r>>1;
            ls = merge(ch[x][0], ch[y][0], l, mid);
            rs = merge(ch[x][1], ch[y][1], mid+1, r);
            up(x);
            return x;
        }
    }T;
    
    int ans[N];
    inline void dfs(int x) {
        for (int i=head[x]; i; i=nxt[i]) {
            dfs(to[i]);
            rt[x] = T.merge(rt[x], rt[to[i]], 1, n);
        }
        ans[x] = T.sum(rt[x], 1, n, a[x] + 1, n);
    }
    
    int main() {
        cin >> n; T.set();
        for (int i=1; i<=n; ++i) {
            scanf("%d", a+i);
            ps.push_back(a[i]);
        }
        sort(ps.begin(), ps.end());
        ps.erase(unique(ps.begin(), ps.end()), ps.end());
        for (int i=1; i<=n; ++i) a[i] = lower_bound(ps.begin(), ps.end(), a[i]) - ps.begin() + 1;
        for (int i=2, par; i<=n; ++i) {
            scanf("%d", &par);
            add(par, i);
        }
        for (int i=1; i<=n; ++i) T.edt(rt[i], 1, n, a[i], 1);
        
        dfs(1);
        
        for (int i=1; i<=n; ++i) printf("%d
    ", ans[i]);
        return 0;
    }
    
    
    
          
    View Code

    线段树: codevs4927 2A 8min

    warning: 区间覆盖后线清空tag标记,然后再传下来的tag标记是在cov之后的,所以要先传cov再传tag

    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    # ifdef WIN32
    # define LLD "%I64d"
    # else
    # define LLD "%lld"
    # endif
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int N = 1e5 + 10, SN = 262144 + 5;
    const int mod = 1e9+7;
    
    int n, m;
    ll a[N];
    
    struct SMT {
        ll s[SN], mx[SN], mi[SN], tag[SN], cov[SN]; bool hc[SN];
        # define ls (x<<1)
        # define rs (x<<1|1)
        inline void up(int x) {
            s[x] = s[ls] + s[rs];
            mx[x] = max(mx[ls], mx[rs]);
            mi[x] = min(mi[ls], mi[rs]);
        }
        inline void pushtag(int x, int l, int r, ll tg) {
            tag[x] += tg; s[x] += tg*(r-l+1);
            mx[x] += tg, mi[x] += tg;
        }
        inline void pushcov(int x, int l, int r, ll tg) {
            tag[x] = 0; hc[x] = 1; cov[x] = tg;
            mx[x] = mi[x] = tg; s[x] = tg * (r-l+1);
        }
        inline void down(int x, int l, int r) {
            int mid = l+r>>1;
            if(hc[x]) {
                pushcov(ls, l, mid, cov[x]);
                pushcov(rs, mid+1, r, cov[x]);
                cov[x] = hc[x] = 0;
            }
            if(tag[x]) {
                pushtag(ls, l, mid, tag[x]);
                pushtag(rs, mid+1, r, tag[x]);
                tag[x] = 0;
            }
        }
        inline void build(int x, int l, int r) {
            tag[x] = cov[x] = hc[x] = 0;
            if(l == r) {
                mx[x] = mi[x] = s[x] = a[l];
                return ;
            }
            int mid = l+r>>1;
            build(ls, l, mid); build(rs, mid+1, r);
            up(x);
        }
        inline void edt(int x, int l, int r, int L, int R, ll p) {
            if(L <= l && r <= R) {
                pushtag(x, l, r, p);
                return ;
            }
            down(x, l, r);
            int mid = l+r>>1;
            if(L <= mid) edt(ls, l, mid, L, R, p);
            if(R > mid) edt(rs, mid+1, r, L, R, p);
            up(x);
        }
        inline void cover(int x, int l, int r, int L, int R, ll p) {
            if(L <= l && r <= R) {
                pushcov(x, l, r, p);
                return ;
            }
            down(x, l, r);
            int mid = l+r>>1;
            if(L <= mid) cover(ls, l, mid, L, R, p);
            if(R > mid) cover(rs, mid+1, r, L, R, p);
            up(x);
        }
        inline ll sum(int x, int l, int r, int L, int R) {
            if(L <= l && r <= R) return s[x];
            down(x, l, r);
            int mid = l+r>>1; ll ret = 0;
            if(L <= mid) ret += sum(ls, l, mid, L, R);
            if(R > mid) ret += sum(rs, mid+1, r, L, R);
            return ret;
        }    
        inline ll gmax(int x, int l, int r, int L, int R) {
            if(L <= l && r <= R) return mx[x];
            down(x, l, r);
            int mid = l+r>>1;
            if(R <= mid) return gmax(ls, l, mid, L, R);
            else if(L > mid) return gmax(rs, mid+1, r, L, R);
            else return max(gmax(ls, l, mid, L, R), gmax(rs, mid+1, r, L, R));
        }    
        inline ll gmin(int x, int l, int r, int L, int R) {
            if(L <= l && r <= R) return mi[x];
            down(x, l, r);
            int mid = l+r>>1;
            if(R <= mid) return gmin(ls, l, mid, L, R);
            else if(L > mid) return gmin(rs, mid+1, r, L, R);
            else return min(gmin(ls, l, mid, L, R), gmin(rs, mid+1, r, L, R));
        }    
    }T;
    
    int main() {
        register int Q, x, y, z;
        register char op[23];
        cin >> n >> Q;
        for (int i=1; i<=n; ++i) scanf(LLD, a+i);
        T.build(1, 1, n);
        while(Q--) {
            scanf("%s%d%d", op, &x, &y);
            if(op[1] == 'd') {
                scanf(LLD, &z);
                T.edt(1, 1, n, x, y, z);
            }
            else if(op[1] == 'e') {
                scanf(LLD, &z);
                T.cover(1, 1, n, x, y, z);
            }
            else if(op[1] == 'u') printf(LLD "
    ", T.sum(1, 1, n, x, y));
            else if(op[1] == 'a') printf(LLD "
    ", T.gmax(1, 1, n, x, y));
            else printf(LLD "
    ", T.gmin(1, 1, n, x, y));
        }
        return 0;
    }
    View Code

    FFT: bzoj2179 1A 10min

    # include <math.h>
    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int M = 262144 + 10;
    const int mod = 1e9+7;
    const ld pi = acos(-1.0);
    
    struct cp {
        ld x, y;
        cp () {}
        cp (ld x, ld y) : x(x), y(y) {}
        inline friend cp operator + (cp a, cp b) {
            return cp(a.x + b.x, a.y + b.y);
        }
        inline friend cp operator - (cp a, cp b) {
            return cp(a.x - b.x, a.y - b.y);
        }
        inline friend cp operator * (cp a, cp b) {
            return cp(a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x);
        }
    }a[M], b[M]; int c[M];
    
    namespace FFT {
        cp w[2][M]; int n, lst[M];
        inline void init(int _n) {
            n = 1;
            while(n < _n) n <<= 1;
            for (int i=0; i<n; ++i) w[0][i] = cp(cos(pi * 2.0 / n * i), sin(pi * 2.0 / n * i)), w[1][i] = cp(w[0][i].x, -w[0][i].y);
            int len = 0;
            while((1 << len) < n) ++len;
            for (int i=0; i<n; ++i) {
                int t = 0;
                for (int j=0; j<len; ++j) if(i & (1<<j)) t |= (1<<(len-j-1));
                lst[i] = t;
            }
        }
            
        inline void DFT(cp *a, int op) {
            cp *o = w[op];
            for (int i=0; i<n; ++i) if(i < lst[i]) swap(a[i], a[lst[i]]);
            for (int len=2; len<=n; len<<=1) {
                int m = (len>>1);
                for (cp *p = a; p != a+n; p += len) {
                    for (int k=0; k<m; ++k) {
                        cp t = o[n/len*k] * p[k+m];
                        p[k+m] = p[k] - t;
                        p[k] = p[k] + t;
                    }
                }
            }
            if(op) for (int i=0; i<n; ++i) a[i].x /= (ld)n, a[i].y /= (ld)n;
        }
    }
    
    int n;
    char str[M];
    
    int main() {
        cin >> n;
        scanf("%s", str);
        FFT :: init(n + n);
        for (int i=0; i<n; ++i) a[i] = cp(str[n-i-1] - '0', 0);
        scanf("%s", str);
        for (int i=0; i<n; ++i) b[i] = cp(str[n-i-1] - '0', 0);
        for (int i=n; i<FFT :: n; ++i) a[i] = b[i] = cp(0, 0);
        FFT :: DFT(a, 0); FFT :: DFT(b, 0);
        for (int i=0; i<FFT :: n; ++i) a[i] = a[i] * b[i];
        FFT :: DFT(a, 1);
        for (int i=0; i<FFT :: n; ++i) c[i] = (int)(a[i].x + 0.5);
        for (int i=0; i<FFT::n; ++i) c[i+1] += c[i] / 10, c[i] %= 10;
        int m = FFT :: n;
        while(c[m] == 0) --m;
        while(~m) printf("%d", c[m--]);
        return 0;
    }
    View Code

    NTT: bzoj2179 1A 10min

    important: 找原根:找到$mod-1$的所有大于1小于$mod$的因数,然后暴力枚举原根$g$,满足条件一定是不存在上述条件的一个因数$x$,使得$g^x = 1$。$998244353$的原根是$3$。

    warning: 记得处处取模。

    # include <math.h>
    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int M = 262144 + 10;
    const int mod = 998244353, G = 3;
    const ld pi = acos(-1.0);
    
    int a[M], b[M]; int c[M];
    
    inline int pwr(int a, int b) {
        int ret = 1;
        while(b) {
            if(b&1) ret = 1ll * ret * a % mod;
            a = 1ll * a * a % mod;
            b >>= 1;
        }
        return ret;
    }
    
    namespace FFT {
        int w[2][M], n, lst[M], inv;
        inline void init(int _n) {
            n = 1;
            while(n < _n) n <<= 1;
            int g = pwr(G, (mod-1)/n), invg = pwr(g, mod-2);
            w[0][0] = w[1][0] = 1;
            for (int i=1; i<n; ++i) w[0][i] = 1ll * w[0][i-1] * g % mod, w[1][i] = 1ll * w[1][i-1] * invg % mod; 
            int len = 0;
            while((1 << len) < n) ++len;
            for (int i=0; i<n; ++i) {
                int t = 0;
                for (int j=0; j<len; ++j) if(i & (1<<j)) t |= (1<<(len-j-1));
                lst[i] = t;
            }
            inv = pwr(n, mod-2);
        }
            
        inline void DFT(int *a, int op) {
            int *o = w[op];
            for (int i=0; i<n; ++i) if(i < lst[i]) swap(a[i], a[lst[i]]);
            for (int len=2; len<=n; len<<=1) {
                int m = (len>>1);
                for (int *p = a; p != a+n; p += len) {
                    for (int k=0; k<m; ++k) {
                        int t = 1ll * o[n/len*k] * p[k+m] % mod;
                        p[k+m] = p[k] - t;
                        if(p[k+m] < 0) p[k+m] += mod;
                        p[k] = p[k] + t;
                        if(p[k] >= mod) p[k] -= mod;
                    }
                }
            }
            if(op) for (int i=0; i<n; ++i) a[i] = 1ll * a[i] * inv % mod;
        }
    }
    
    int n;
    char str[M];
    
    int main() {
        cin >> n;
        scanf("%s", str);
        FFT :: init(n + n);
        for (int i=0; i<n; ++i) a[i] = str[n-i-1] - '0';
        scanf("%s", str);
        for (int i=0; i<n; ++i) b[i] = str[n-i-1] - '0';
        for (int i=n; i<FFT :: n; ++i) a[i] = b[i] = 0;
        FFT :: DFT(a, 0); FFT :: DFT(b, 0);
        for (int i=0; i<FFT :: n; ++i) a[i] = 1ll * a[i] * b[i] % mod;
        FFT :: DFT(a, 1);
        for (int i=0; i<FFT :: n; ++i) c[i] = a[i];
        for (int i=0; i<FFT :: n; ++i) c[i+1] += c[i] / 10, c[i] %= 10;
        int m = FFT :: n;
        while(c[m] == 0) --m;
        while(~m) printf("%d", c[m--]);
        return 0;
    }
    View Code

    网络流(Dinic): szoj334 1A 10min

    warning: 记得清空队列。

    # include <queue>
    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int N = 3e3 + 10, M = 4e5 + 10;
    const int mod = 1e9+7, inf = 1e9;
    
    int n, m, S, T;
    namespace MF {
        int head[N], nxt[M], to[M], flow[M], tot = 1;
        inline void add(int u, int v, int fl) {
            ++tot; nxt[tot] = head[u]; head[u] = tot;
            to[tot] = v; flow[tot] = fl;
        }
        inline void adde(int u, int v, int fl) {
            add(u, v, fl), add(v, u, 0);
        }
        queue<int> q;
        int c[N];
        inline bool bfs() {
            for (int i=1; i<=n; ++i) c[i] = -1;
            while(!q.empty()) q.pop();
            q.push(S); c[S] = 0;
            while(!q.empty()) {
                int top = q.front(); q.pop();
                for (int i=head[top]; i; i=nxt[i]) {
                    if(c[to[i]] != -1 || !flow[i]) continue;
                    c[to[i]] = c[top] + 1;
                    q.push(to[i]);
                    if(to[i] == T) return 1;
                }
            }
            return 0;
        }
        
        int cur[N];
        inline int dfs(int x, int low) {
            if(x == T) return low;
            int r = low, fl;
            for (int i=cur[x]; i; i=nxt[i]) {
                if(c[to[i]] != c[x]+1 || !flow[i]) continue;
                fl = dfs(to[i], min(r, flow[i]));
                r -= fl; flow[i] -= fl; flow[i^1] += fl;
                if(flow[i] > 0) cur[x] = i;
                if(!r) return low;
            }
            if(low == r) c[x] = -1;
            return low-r;
        }
        
        inline int main() {
            int res = 0;
            while(bfs()) {
                for (int i=1; i<=n; ++i) cur[i] = head[i];
                res += dfs(S, inf);
            }
            return res;
        }
    }
    
    int main() {
        cin >> n >> m; S=1, T=n;
        for (int i=1, u, v, fl; i<=m; ++i) {
            scanf("%d%d%d", &u, &v, &fl);
            MF :: adde(u, v, fl);
        }
        cout << MF :: main();
        return 0;
    }
    View Code

    费用流: bzoj3876 1A 10min

    # include <queue>
    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int M = 3e5 + 10;
    const int mod = 1e9+7, inf = 1e9;
    
    int n, deg[M], S, T; 
    
    namespace MCF {
        int head[M], nxt[M], to[M], w[M], flow[M], tot = 1;
        inline void add(int u, int v, int fl, int _w) {
            ++tot; nxt[tot] = head[u]; head[u] = tot; to[tot] = v; w[tot] = _w, flow[tot] = fl;
        }
        inline void adde(int u, int v, int fl, int _w) {
            add(u, v, fl, _w);
            add(v, u, 0, -_w);
        }
        ll d[M]; int pre[M]; bool vis[M];
        queue<int> q; 
        inline bool spfa() {
            for (int i=1; i<=T; ++i) vis[i] = pre[i] = 0, d[i] = 1e18; 
            d[S] = 0; vis[S] = 1; q.push(S); 
            while(!q.empty()) {
                int top = q.front(); q.pop(); vis[top] = 0;
                for (int i=head[top]; i; i=nxt[i]) {
                    if(d[to[i]] > d[top] + w[i] && flow[i]) {
                        d[to[i]] = d[top] + w[i];
                        pre[to[i]] = i; 
                        if(!vis[to[i]]) {
                            vis[to[i]] = 1;
                            q.push(to[i]);
                        }
                    }
                }
            }
            return d[T] < 1e18;
        }
        inline ll mcf() {
            int xm = inf; ll ans = 0;
            for (int i=pre[T]; i; i=pre[to[i^1]]) xm = min(xm, flow[i]);
            for (int i=pre[T]; i; i=pre[to[i^1]]) {
                flow[i] -= xm, flow[i^1] += xm;
                ans += 1ll * xm * w[i];    
            }
            return ans;
        }
        inline ll main() {
            ll ans = 0;
            while(spfa()) ans += mcf();
            return ans;
        }
    }
            
            
            
    int main() {
        ll ans = 0;
        cin >> n;
        for (int i=1, t, B, T; i<=n; ++i) {
            scanf("%d", &t);
            while(t--) {
                scanf("%d%d", &B, &T); 
                MCF :: adde(i, B, inf, T);
                deg[B] ++; deg[i] --; ans += T;
            }
            if(i != 1) MCF :: adde(i, 1, inf, 0); 
        }
        S = n+1, T = n+2;
        for (int i=1; i<=n; ++i) {
            if(deg[i] > 0) MCF :: adde(S, i, deg[i], 0);
            if(deg[i] < 0) MCF :: adde(i, T, -deg[i], 0); 
        }
        cout << MCF :: main() + ans << endl; 
        return 0;
    }
    View Code

    ========================================分割线==========================================

    【有上下界网络流集合】

    1. 无源汇最大流:增加S和T,对于边(a->b, [c, d]),连(a->b, d-c), (a->T, c), (S->b, c)。注意这个部分可以整合顶点连出去的所有边,汇总流量。对于S到T做最大流,如果每条S连出去的和连到T的边都流满了,说明有可行流。

    2. 有源汇最大流:连(T->S, [0, inf])后就和无源汇可行流一样了。建立超级源汇SS、TT,按照无源汇最大流的方法做,判断是否有可行解。有可行流后,删除超级源汇SS、TT,从S到T做最大流,两次的和就是答案了。(第一次保证下界流满,第二次补流)。【需要注意要去掉(T->S, inf)的边】

    3. 有源汇最小流:先不连(T->S, inf),跑一遍SS到TT最大流,再连边,跑最大流,那么答案就是这条边的反向弧。

    4. 最小费用可行流:按照无源汇最大流一样连,然后上费用流即可。

    ========================================分割线==========================================

    高斯消元: bzoj1013 1A 13min(推式子推了好久)

    # include <math.h>
    # include <stdio.h>
    # include <assert.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int M = 5e5 + 10;
    const int mod = 1e9+7;
    const ld eps = 1e-7;
    
    inline ld getld() {
        static double x;
        scanf("%lf", &x);
        return (ld)x;
    }
    
    int n;
    ld z[23][23]; 
    ld a[23][23], b[23]; 
    
    inline bool iszero(ld x) {
        return fabs(x) < eps;
    }
    
    inline void gauss() {
        for (int i=1; i<=n; ++i) {
            int p = -1;
            for (int j=i; j<=n; ++j) if(!iszero(a[j][i])) {p = j; break;}
            assert(p != -1);    // inf
            for (int j=1; j<=n; ++j) swap(a[p][j], a[i][j]);
            swap(b[p], b[i]);
            for (int j=i+1; j<=n; ++j) {
                ld x = a[i][i] / a[j][i];
                for (int k=i; k<=n; ++k) a[j][k] = a[j][k] * x - a[i][k];
                b[j] = b[j] * x - b[i];
            }
        }
        
        for (int i=n; i; --i) {
            b[i] = b[i] / a[i][i];
            for (int j=1; j<i; ++j) b[j] -= a[j][i] * b[i];
        }
    }
                
    int main() {
        cin >> n;
        for (int i=1; i<=n+1; ++i) 
            for (int j=1; j<=n; ++j) z[i][j] = getld();
        for (int i=1; i<=n; ++i) {
            for (int j=1; j<=n; ++j) {
                a[i][j] = 2.0 * (z[i][j] - z[i+1][j]);
                b[i] = b[i] + (z[i][j] * z[i][j] - z[i+1][j] * z[i+1][j]);
            }
        }
        gauss();
        for (int i=1; i<=n; ++i) printf("%.3lf%c", (double)b[i], i==n ? '
    ' : ' ');
        puts("");
        return 0;
    }
    View Code

    主席树:bzoj3524 1A 8min

    warning: 需要注意节点数量为$O(nlogn)$。

    http://www.cnblogs.com/galaxies/p/bzoj3524.html

    ========================================分割线==========================================

    好累啊休息一下

    早上抽空看了个《Going in Style》,三个老头演的真好啊qwq(逃

    ========================================分割线==========================================

    LCA,树链剖分: bzoj3083 3A 20min(2个WA都不是模板的问题,是自己傻逼了。。)

    http://www.cnblogs.com/galaxies/p/bzoj3083.html

    warning: 树链剖分放在边上的话,要注意不能把lca代表的边算进去!!!

    BIT区修区查: codevs1082 1A 5min

    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int M = 5e5 + 10;
    const int mod = 1e9+7;
    
    struct BIT {
        ll c[M]; int  n;
        # define lb(x) (x & (-x)) 
        inline void set(int _n) { 
            memset(c, 0, sizeof c); n = _n; 
        }
        inline void edt(int x, ll d) {
            for (; x<=n; x+=lb(x)) c[x] += d;
        }
        inline ll sum(int x) {
            ll ret = 0;
            for (; x; x-=lb(x)) ret += c[x];
            return ret;
        }
        # undef lb 
    };
    
    struct BIT2 {
        BIT a, b;
        inline void set(int n) {
            a.set(n), b.set(n);
        }
        inline void edt(int x, int y, int d) {
            a.edt(x, d); a.edt(y+1, -d);
            b.edt(x, 1ll * d * x), b.edt(y+1, -1ll * d * (y+1)); 
        }
        inline ll sum(int x) {
            return a.sum(x) * (x+1) - b.sum(x);
        }
        inline ll sum(int x, int y) {
            if(x > y) return 0;
            return sum(y) - sum(x-1); 
        }
    }T;
    
    int n;
    
    int main() {
        cin >> n; T.set(n); 
        for (int i=1, t; i<=n; ++i) {
            scanf("%d", &t); 
            T.edt(i, i, t);    
        }
        int Q, op, l, r, d; cin >> Q;
        while(Q--) {
             scanf("%d%d%d", &op, &l, &r);
            if(op == 1) {
                scanf("%d", &d);
                T.edt(l, r, d);
            } else printf("%lld
    ", T.sum(l, r));
        }
        return 0;
    }
    View Code

    线性基: bzoj2460 2A 10min(没开long long)

    conclusion: (这题没用)考虑$n$个数组成的基,大小为$k$,那么每种方案都有$2^{n-k}$可以取到。 

    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int M = 5e5 + 10;
    const int mod = 1e9+7;
    
    int n;
    struct pa {
        ll a; int b;
        friend bool operator < (pa a, pa b) {
            return a.b > b.b;
        }
    }p[M]; 
    int Lbase[65]; 
    
    # define bit(x, i) (((x) >> (i)) & 1) 
    
    int main() {
        ll ans = 0;
        cin >> n;
        for (int i=1; i<=n; ++i) scanf("%lld%d", &p[i].a, &p[i].b);
        sort(p+1, p+n+1); 
        for (int i=1; i<=n; ++i) {
            ll t = p[i].a;
            for (int j=62; ~j; --j) {
                if(bit(t, j)) {
                    if(!Lbase[j]) {
                        Lbase[j] = t;
                        break;
                    }
                    t ^= Lbase[j]; 
                }
            }
            if(t) ans += p[i].b; 
        }
        cout << ans; 
        return 0;
    }
    View Code

    点分治: poj1741 2A 10min

    warning: 如果是涉及根的统计,注意容斥的时候对其子树,需要有本来的那条边的长度!

    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int N = 1e4 + 10, M = 2e4 + 10;
    const int mod = 1e9+7;
    
    # define RG register
    # define ST static
    
    int n, m, head[M], nxt[M], to[M], w[M], tot = 0;
    inline void add(int u, int v, int _w) {
        ++tot; nxt[tot] = head[u]; head[u] = tot; to[tot] = v; w[tot] = _w;
    }
    inline void adde(int u, int v, int _w) {
        add(u, v, _w), add(v, u, _w);
    }
    
    int ans = 0;
    namespace DFZ {
        bool vis[N];
        int sz[N], mx[N];
        
        inline void dfssz(int x, int fa = 0) {
            sz[x] = 1; mx[x] = 0;
            for (int i=head[x]; i; i=nxt[i]) {
                if(to[i] == fa || vis[to[i]]) continue;
                dfssz(to[i], x);
                sz[x] += sz[to[i]];
                if(sz[to[i]] > mx[x]) mx[x] = sz[to[i]];
            }
        }
        
        int mi, centre;
        inline void dfscentre(int x, int tp, int fa = 0) {
            if(sz[tp] - sz[x] > mx[x]) mx[x] = sz[tp] - sz[x];
            if(mx[x] < mi) mi = mx[x], centre = x;
            for (int i=head[x]; i; i=nxt[i]) {
                if(to[i] == fa || vis[to[i]]) continue;
                dfscentre(to[i], tp, x);
            }
        }
        
        int c[N], cn;
        inline void dfsans(int x, int fa, int d) {
            if(d > m) return ;
            c[++cn] = d;
            for (int i=head[x]; i; i=nxt[i]) {
                if(to[i] == fa || vis[to[i]]) continue;
                dfsans(to[i], x, d+w[i]);
            }
        }
        
        inline int calc(int x, int fa, int d) {
            int ret = 0;
            cn = 0;
            dfsans(x, fa, d);
            sort(c+1, c+cn+1);
            for (int i=1, j=cn; i<=n; ++i) {
                while(j && c[i] + c[j] > m) --j;
                if(j < i) break;
                ret += (j-i);
            }
            return ret;
        }
        
        inline void dfs(int x) {
            dfssz(x); mi = n;
            dfscentre(x, x);
            x = centre;
            ans += calc(x, 0, 0);    
            vis[x] = 1;
            for (int i=head[x]; i; i=nxt[i])
                if(!vis[to[i]]) {
                    ans -= calc(to[i], x, w[i]);
                    dfs(to[i]);
                }
        }
        
        inline void main() {
            memset(vis, 0, sizeof vis);
            dfs(1);
        }
    }
    
    int main() {
        while(cin >> n >> m && (n+m)) {
            for (int i=1, u, v, _w; i<n; ++i) {
                scanf("%d%d%d", &u, &v, &_w);
                adde(u, v, _w);
            }
            ans = 0;
            DFZ :: main();
            cout << ans << endl;
            tot = 0;
            fill(head+1, head+n+1, 0);
        }
        return 0;
    }
    View Code

    Splay: bzoj3224 2A 20min

    warning: 需要注意每次操作都要splay下保证复杂度。

    http://www.cnblogs.com/galaxies/p/bzoj3224.html

    莫队: bzoj2038 1A 7min

    http://www.cnblogs.com/galaxies/p/bzoj2038.html

    字符串哈希: noi2016 day1t1 95pts: 1A 10min

    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int M = 3e4 + 10;
    const int mod = 1e9+7;
    const ull HA = 20000713;
    
    int n;
    char s[M];
    ull h[M], base[M];
    
    inline void gh() {
        h[0] = 0;
        for (int i=1; i<=n; ++i) h[i] = h[i-1] * HA + (s[i] - 'a' + 1);
    }
    
    inline ull ha(int i, int j) {
        return h[j] - h[i-1] * base[j-i+1];
    }
    
    
    inline void sol() {
        scanf("%s", s+1); n = strlen(s+1);
        gh();
        ll ans = 0;    
        for (int i=1; i<n; ++i) {
            int cnt1 = 0, cnt2 = 0;
            for (int j=i-1, k=i; j>=1; j-=2, --k)
                if(ha(j, k-1) == ha(k, i)) ++cnt1;
            for (int j=i+2, k=i+1; j<=n; j+=2, ++k) 
                if(ha(i+1, k) == ha(k+1, j)) ++cnt2;
    //        cout << i << ' ' << cnt1 << ' ' << cnt2 << endl;
            ans += 1ll * cnt1 * cnt2;
        }
        printf("%lld
    ", ans);
    }
    
    
    int main() {
        base[0] = 1;
        for (int i=1; i<=30000; ++i) base[i] = base[i-1] * HA;
        int T; cin >> T;
        while(T--) sol();
        return 0;
    }
    View Code

    tarjan: szoj9 2A

    warning: 注意判断是否在栈中,找环可以用并查集,找到在环上的点,顺着dfs即可。

    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int M = 5e5 + 10;
    const int mod = 1e9+7;
    
    int n, m;
    int head[M], nxt[M], to[M], tot = 0;
    
    inline void add(int u, int v) {
        ++tot; nxt[tot] = head[u]; head[u] = tot; to[tot] = v;
    }
    
    
    int dfn[M], low[M], DFN = 0;
    bool ins[M]; int st[M], stn = 0;
    int belong[M], p[M], scc;
    
    inline void tarjan(int x) {
        dfn[x] = low[x] = ++DFN; st[++stn] = x; ins[x] = 1;
        for (int i=head[x]; i; i=nxt[i]) {
            if(!dfn[to[i]]) {
                tarjan(to[i]);
                low[x] = min(low[x], low[to[i]]);
            } else if(ins[to[i]]) low[x] = min(low[x], dfn[to[i]]);
        }
        if(dfn[x] == low[x]) {
            ++scc; int t = 0;
            while(t != x) {
                t = st[stn--];
                ins[t] = 0; belong[t] = scc;
            }
        }
    }
    
    int main() {
        cin >> n >> m;
        for (int i=1, u, v; i<=m; ++i) {
            scanf("%d%d", &u, &v);
            add(u, v);
        }
        for (int i=1; i<=n; ++i) if(!dfn[i]) tarjan(i);
        for (int i=1; i<=n; ++i) p[belong[i]] ++;
        int ans = 0;
        for (int i=1; i<=scc; ++i) ans = max(ans, p[i]);
        cout << ans;
        return 0;
    }
    View Code

    FWT: 就看看就行

    1. 如果是异或(xor)卷积的话:
    $A_0$和$A_1$是按照$A$的最高位分成的两部分
    $f(A) = (f(A_0) + f(A_1), f(A_0) - f(A_1))$
    $f_T(A) = (f_T(frac{A_0 + A_1}{2}), f_T(frac{A_0 - A_1}{2}))$
    正确性可以用归纳法证明。
    其实只要记住正变换的式子即可,逆变换可以从正变换推导出来。

    2. 如果是与(and)卷积的话
    $f(A) = (f(A_0) + f(A_1), f(A_1))$
    $f_T(A) = (f_T(A_0) - f_T(A_1), f_T(A_1))$

    3. 如果是或(or)卷积的话
    $f(A) = (f(A_0), f(A_1) + f(A_0))$
    $f_T(A) = (f_T(A_0), f_T(A_1) - f_T (A_0))$

    直接套FFT板子即可。

    后缀自动机: hihocoder1445 1A 10min

    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int M = 1e6 + 10;
    const int mod = 1e9+7;
    
    
    struct SAM {
        int ch[M + M][26], par[M + M], ml[M + M];
        int rt, lst, siz;
        inline void set() {
            rt = lst = siz = 1;
        }
        inline void extend(int c) {
            int p = lst, cur = ++siz; ml[cur] = ml[p]+1;
            for (; p && !ch[p][c]; p = par[p]) ch[p][c] = cur;
            if(!p) par[cur] = rt;
            else {
                int q = ch[p][c];
                if(ml[q] == ml[p] + 1) par[cur] = q;
                else {
                    int sq = ++siz; par[sq] = par[q];
                    for (int i=0; i<26; ++i) ch[sq][i] = ch[q][i];
                    ml[sq] = ml[p] + 1;
                    par[q] = par[cur] = sq;
                    for (; p && ch[p][c] == q; p = par[p]) ch[p][c] = sq;
                }
            }
            lst = cur;
        }
    }S;
    
    char s[M];
    
    int main() {
        S.set(); ll ans = 0;
        scanf("%s", s);
        for (int i=0; s[i]; ++i) S.extend(s[i] - 'a');
        for (int i=2; i<=S.siz; ++i) 
            ans += S.ml[i] - S.ml[S.par[i]];
        
        cout << ans;
        return 0;
    }
    View Code

    模拟退火: 记得调参,和是否选择“可以接受更劣答案”。

    KDTREE: bzoj2683 2A 一个小地方写错了。。 25min

    # include <math.h>
    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int M = 5e5 + 10;
    const int mod = 1e9+7;
    
    inline ll read() {
        ll x = 0, f = 1; char ch = getchar();
        while(!isdigit(ch)) {
            if(ch == '-') f = -1;
            ch = getchar();
        }
        while(isdigit(ch)) {
            x = x*10+ch-'0';
            ch = getchar();
        }
        return x*f;
    }
    
    int D;
    struct node {
        int mi[2], mx[2], d[2], l, r, siz;
        ll v, s;
        inline friend bool operator == (node a, node b) {
            return a.d[0] == b.d[0] && a.d[1] == b.d[1];
        }
        inline friend bool operator < (node a, node b) {
            return a.d[D] < b.d[D];
        }
    };
    
    inline bool in(int x1, int y1, int x2, int y2, int xx1, int yy1, int xx2, int yy2) {
        return x1 <= xx1 && xx2 <= x2 && y1 <= yy1 && yy2 <= y2;    
    }
    
    inline bool out(int x1, int y1, int x2, int y2, int xx1, int yy1, int xx2, int yy2) {
        return x1 > xx2 || x2 < xx1 || y1 > yy2 || y2 < yy1;
    }
    
    inline int cmp(int, int);
    
    const double REBUILD_FAC = 0.713, REBUILD_LOG = log(1.0 - REBUILD_FAC);
    
    node tmp;
    struct KDT {
        node T[M];
        # define ls (T[x].l)
        # define rs (T[x].r)
        int siz, p[M], pn, rt;
        inline void set() {siz = rt = 0;}
        inline void up(int x) {
            for (int i=0; i<2; ++i) {
                T[x].mi[i] = T[x].mx[i] = T[x].d[i];
                if(ls) T[x].mi[i] = min(T[x].mi[i], T[ls].mi[i]), T[x].mx[i] = max(T[x].mx[i], T[ls].mx[i]);
                if(rs) T[x].mi[i] = min(T[x].mi[i], T[rs].mi[i]), T[x].mx[i] = max(T[x].mx[i], T[rs].mx[i]);
            }
            T[x].s = T[ls].s + T[rs].s + T[x].v;
            T[x].siz = 1 + T[ls].siz + T[rs].siz;
        }
        inline bool ins(int &x, int d, int dep) {
            if(!x) {
                x = ++siz;
                for (int i=0; i<2; ++i)
                    T[x].mi[i] = T[x].mx[i] = T[x].d[i] = tmp.d[i];
                T[x].siz = 1; T[x].v = tmp.v; T[x].s = tmp.s;
                return dep * REBUILD_LOG > log(siz);
            }
            if(tmp == T[x]) {
                T[x].v += tmp.v;
                T[x].s += tmp.v;
                return 0;
            }
            int id; bool ret;
            if(tmp.d[d] < T[x].d[d]) ret = ins(ls, d^1, dep+1), id = ls;
            else ret = ins(rs, d^1, dep+1), id = rs;
            up(x);
            if(ret) {
                if(T[id].siz > REBUILD_FAC * T[x].siz) {
                    x = rebuild(x, d);
                    return 0;
                }
                return 1;
            }
        }
        
        inline ll query(int x, int x1, int y1, int x2, int y2) {
            if(!x) return 0;
            if(in(x1, y1, x2, y2, T[x].mi[0], T[x].mi[1], T[x].mx[0], T[x].mx[1])) return T[x].s;
            if(out(x1, y1, x2, y2, T[x].mi[0], T[x].mi[1], T[x].mx[0], T[x].mx[1])) return 0;
            ll ret = 0;
            if(in(x1, y1, x2, y2, T[x].d[0], T[x].d[1], T[x].d[0], T[x].d[1])) ret += T[x].v;
            ret += query(ls, x1, y1, x2, y2) + query(rs, x1, y1, x2, y2);
            return ret;
        }
        
        inline int build(int l, int r, int d) {
            if(l > r) return 0;
            int mid = l+r>>1; D = d;
            nth_element(p+l, p+mid, p+r+1, cmp);
            int x = p[mid];
            ls = build(l, mid-1, d^1);
            rs = build(mid+1, r, d^1);
            up(x);
            return x;
        }
        
        inline void getnode(int x) {
            if(!x) return ;
            p[++pn] = x;
            getnode(ls);
            getnode(rs);
        }
        
        inline int rebuild(int x, int d) {
            pn = 0; getnode(x);    
            return build(1, pn, d);
        }
    }T;
    
    inline int cmp(int a, int b) {
        return T.T[a] < T.T[b];
    }
    
    int main() {
        int op, x1, y1, x2, y2, ad;
        ll lst = 0;
        scanf("%d", &op); T.set();
        while(1) {
            scanf("%d", &op);
            if(op == 3) break;
            if(op == 1) {
                x1 = read() ^ lst, y1 = read() ^ lst, ad = read() ^ lst;
                tmp.d[0] = x1, tmp.d[1] = y1, tmp.v = tmp.s = ad;
                T.ins(T.rt, 0, 1);
            } else {
                x1 = read() ^ lst, y1 = read() ^ lst, x2 = read() ^ lst, y2 = read() ^ lst;
                printf("%lld
    ", T.query(T.rt, x1, y1, x2, y2));
            }
        }
        return 0;
    }
    View Code

    AC自动机,fail树: bzoj3172 1A 20min

    # include <queue>
    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int M = 1.6e6 + 10;
    const int mod = 1e9+7;
    
    int n; char t[M];
    int v[M], ps[M]; vector<int> G[M];
    struct ACM {
        int ch[M][26], fail[M], siz, isend[M];
        inline void set() {siz = 0;}
        inline int ins(char *t) {
            int p = 0;
            for (int i=0; t[i]; ++i) {
                int c = t[i] - 'a';
                if(!ch[p][c]) ch[p][c] = ++siz;
                p = ch[p][c];
                v[p] ++;
            }
            return p;
        }
        queue<int> q;
        inline void build() {
            while(!q.empty()) q.pop();
            for (int c=0; c<26; ++c) {
                int p = ch[0][c];
                if(p) {
                    fail[p] = 0;
                    q.push(p);
                }
            }
            while(!q.empty()) {
                int top = q.front(); q.pop();
                for (int c=0; c<26; ++c) {
                    int p = ch[top][c];
                    if(!p) {
                        ch[top][c] = ch[fail[top]][c];
                        continue;
                    }
                    q.push(p);
                    int v = fail[top];
                    while(v && !ch[v][c]) v = fail[v];
                    fail[p] = ch[v][c];
                }
            }
        }
        inline void getfail() {
            for (int i=1; i<=siz; ++i) 
                G[fail[i]].push_back(i);
        }
    }S;
    
    inline void dfs(int x) {
        for (int i=0; i<G[x].size(); ++i) {
            int y = G[x][i];
            dfs(y);
            v[x] += v[y];
        }
    }
    
    int main() {
        cin >> n; S.set();
        for (int i=1; i<=n; ++i) {
            scanf("%s", t);
            ps[i] = S.ins(t);
        }
        S.build();
        S.getfail();
        dfs(0);
        for (int i=1; i<=n; ++i) printf("%d
    ", v[ps[i]]);
        return 0;
    }
    View Code

    那么就不管kmp了吧……kmp能做的AC自动机都能做

    剩余复习内容:

    1. SA(明天晚上)

    noi 加油!

     

  • 相关阅读:
    [转载]Axis2 and CXF的比较
    [转载]Axure RP 7.0下载地址及安装说明
    Eclipse配置总结
    201505大事记
    Gmail收不到邮件咋办?
    Mybatis-There is no getter for property named 'id' in 'class java.lang.String'
    EXTjs+SpringMVC+Mybatis实现照片的上传,下载,查看关键技术整理
    Ext如何Gird中如何显示时间类型的列?
    glibc
    圆形头像CircleImageView和Cardview使用
  • 原文地址:https://www.cnblogs.com/galaxies/p/template.html
Copyright © 2020-2023  润新知