存一下板子

fft

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <cmath>
#include <algorithm>
#define MAXN 1000000
using namespace std;

const double pi = acos (-1);

struct cmplx {
    double r, i;
    inline cmplx () {r = i = 0;}
    inline cmplx (double x, double y) {r = x, i = y;}
    inline cmplx operator + (cmplx &x) {return cmplx (r + x.r, i + x.i);}
    inline cmplx operator - (cmplx &x) {return cmplx (r - x.r, i - x.i);}
    inline cmplx operator * (cmplx &x) {return cmplx (r * x.r - i * x.i, r * x.i + i * x.r);}
    inline void operator += (cmplx &x) {r += x.r, i += x.i;}
    inline void operator *= (cmplx &x) {double t = r; r = r * x.r - i * x.i, i = t * x.i + i * x.r;}
}f[MAXN], g[MAXN];

int r[MAXN], n, m, lim;

inline int read () {
    register int s = 0, w = 1;
    register char ch = getchar ();
    while (! isdigit (ch)) {if (ch == '-') w = -1; ch = getchar ();}
    while (isdigit (ch)) {s = (s << 3) + (s << 1) + (ch ^ 48); ch = getchar ();}
    return s * w;
}

inline void FFT (cmplx *a, int opt) {
    for (register int i = 0; i < lim; i++) if (i < r[i]) swap (a[i], a[r[i]]);
    for (register int i = 1; i < lim; i <<= 1) {
        cmplx x = cmplx (cos (pi / i), sin (pi / i) * opt);
        for (register int j = 0; j < lim; j += (i << 1)) {
            cmplx y = cmplx (1, 0);
            for (register int k = 0; k < i; k++, y *= x) {
                cmplx p = a[j + k], q = a[i + j + k] * y;
                a[j + k] = p + q, a[i + j + k] = p - q;
            }
        }
    }
}

int main () {
    n = read (), m = read (); int l = 0;
    for (register int i = 0; i <= n; i++) f[i].r = read ();
    for (register int i = 0; i <= m; i++) g[i].r = read ();
    for (lim = 1; lim <= n + m; lim <<= 1) l++;
    for (register int i = 0; i < lim; i++) r[i] = (r[i >> 1] >> 1) | ((i & 1) << (l - 1));
    FFT (f, 1), FFT (g, 1);
    for (register int i = 0; i <= lim; i++) f[i] *= g[i];
    FFT (f, -1);
    for (register int i = 0; i <= n + m; i++) printf ("%d ", (int) (0.5 + f[i].r / lim));
    return 0;
}

bsgs

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <map>
#include <algorithm>
#define int long long
using namespace std;

int p, a, b, ans;

int pow (int a, int b, int qy) {
    if (! b) return 1; if (b == 1) return a;
    int base = 1;
    while (b) {
        if (b & 1) base *= a, base %= qy;
        a *= a, a %= qy, b >>= 1;
    }
    return base;
}

int BSGS (int a, int b, int qy) {
    map <int, int> hash;
    int lim = ceil (sqrt (qy)), base = b % qy;
    for (register int i = 1; i <= lim; i++) {
        base = base * a % qy; hash[base] = i;
    }
    base = pow (a, lim, qy);
    int o = 1;
    for (register int i = 1; i <= lim; i++) {
        o *= base, o %= qy;
        if (hash[o]) return ((i * lim - hash[o]) % qy + qy) % qy;
    }
    return -1;
}

signed main () {
    scanf ("%lld%lld%lld", &p, &a, &b);
    if (a % p == 0) puts ("no solution");
    else {
        int ans = BSGS (a, b, p);
        if (ans == -1) puts ("no solution");
        else printf ("%lld\n", ans);
    }
    return 0;
}

LCT

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#define MAXN 500000
using namespace std;

int father[MAXN], val[MAXN], son[MAXN][3], a[MAXN], stack[MAXN], n, m;
bool rev[MAXN];

inline int read () {
    register int s = 0, w = 1;
    register char ch = getchar ();
    while (! isdigit (ch)) {if (ch == '-') w = -1; ch = getchar ();}
    while (isdigit (ch)) {s = (s << 3) + (s << 1) + (ch ^ 48); ch = getchar ();}
    return s * w;
}

struct lct {
    
    inline bool isroot (int x) {
        return ! (son[father[x]][0] == x || son[father[x]][1] == x);
    }
    
    inline void maintain (int x) {
        val[x] = a[x] ^ val[son[x][0]] ^ val[son[x][1]];
    }
    
    inline void pushrev (int x) {
        swap (son[x][0], son[x][1]), rev[x] ^= 1;
    }
    
    inline void pushdown (int x) {
        if (rev[x]) {
            if (son[x][0]) pushrev (son[x][0]);
            if (son[x][1]) pushrev (son[x][1]);
            rev[x] ^= 1;
        }
    }
    
    inline void rotate (int x) {
        int y = father[x], z = father[y];
        int k = son[y][1] == x, kk = son[z][1] == y;
        if (! isroot (y)) son[z][kk] = x;
        father[x] = z;
        son[y][k] = son[x][k ^ 1];
        father[son[x][k ^ 1]] = y;
        son[x][k ^ 1] = y;
        father[y] = x;
        maintain (y), maintain (x);
    }
    
    inline void splay (int x) {
        int top = 0; stack[++top] = x;
        for (register int i = x; ! isroot (i); i = father[i]) stack[++top] = father[i];
        for (register int i = top; i; i--) pushdown (stack[i]);
        while (! isroot (x)) {
            int y = father[x], z = father[y];
            if (! isroot (y))
                (son[y][1] == x) ^ (son[z][1] == y)
                    ? rotate (x) : rotate (y);
            rotate (x);
        }
        maintain (x);
    }
    
    inline void access (int x) {for(int y=0;x;x=father[y=x])splay(x),son[x][1]=y,maintain(x);}
    inline void makeroot (int x) {access(x),splay(x),pushrev(x);}
    inline int findroot (int x) {access(x),splay(x);while(son[x][0])pushdown(x=son[x][0]);splay(x);return x;}
    inline void split (int x,int y) {makeroot(x),access(y),splay(y);}
    inline void link (int x,int y) {makeroot(x);if (findroot(y)!=x)father[x]=y;}
    inline void cut (int x,int y) {makeroot(x);if (findroot(y)==x&&father[y]==x&&!son[y][0])father[y]=son[x][1]=0,maintain(x);}
    inline void query (int x,int y) {split(x,y);printf("%d\n",val[y]);}
    inline void modify (int x,int y) {splay(x),a[x]=y;}	
    
}tree;

int main () {
    n = read (), m = read ();
    for (register int i = 1; i <= n; i++) a[i] = read ();
    for (register int i = 1; i <= m; i++) {
        int opt = read (), x = read (), y = read ();
        if (opt == 0) tree.query (x, y);
        if (opt == 1) tree.link (x, y);
        if (opt == 2) tree.cut (x, y);
        if (opt == 3) tree.modify (x, y);
    }
    return 0;
}

树链剖分

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#define MAXN 200010
#define int long long
#define read(a) a = SlowRead <int> ()
#define rep(x,y,z) for (register int x = y; x <= z; x++) 
#define cross(x,y) for (register int x = head[now]; x; x = edge[x].next)
using namespace std;

struct fls {
    int next, to;
}edge[MAXN];

int n, q, root, qy;
int tree[MAXN << 2], lazy[MAXN << 2];
int id[MAXN], rk[MAXN], a[MAXN], father[MAXN], depth[MAXN];
int top[MAXN], size[MAXN], son[MAXN], head[MAXN << 2], cnt, dfn, res, ans;

template <typename _T> inline _T SlowRead () {
    register int s = 0, w = 1;
    register char ch = getchar ();
    while (! isdigit (ch)) {if (ch == '-')w = -1; ch = getchar ();}
    while (isdigit (ch)) {s = (s << 3) + (s << 1) + ch - '0'; ch = getchar ();}
    return s * w;
} 

inline void connect (int u, int v) {
    edge[++cnt].to = v;
    edge[cnt].next = head[u];
    head[u] = cnt;
}

namespace segtree {

    inline void pushup (int now) {
        tree[now] = tree[now << 1] + tree[now << 1 | 1];
        tree[now] %= qy;
    }

    inline void pushdown (int now, int l, int r) {
        int mid = (l+r) >> 1;
        lazy[now << 1] += lazy[now];
        lazy[now << 1 | 1] += lazy[now];
        tree[now << 1] += lazy[now] * (mid-l+1);
        tree[now << 1 | 1] += lazy[now] * (r-mid);
        tree[now << 1 ] %= qy;
        tree[now << 1 | 1] %= qy;
        lazy[now] = 0;
    }

    void build (int now, int l, int r) {
        if (l == r) {
            tree[now] = a[rk[l]];
            tree[now] %= qy;
            return;
        }
        int mid = (l+r) >> 1;
        build (now << 1, l, mid);
        build (now << 1 | 1, mid+1, r);
        pushup (now);
    }

    void update (int now, int l, int r, int L, int R, int change) {
        if (R < l || r < L)return;
        if (L <= l && r <= R) {
            tree[now] += change * (r-l+1);
            lazy[now] += change; return;
        }
        if (lazy[now])pushdown (now, l, r);
        int mid = (l+r) >> 1;
        update (now << 1, l, mid, L, R, change);
        update (now << 1 | 1, mid+1, r, L, R, change);
        pushup (now);
    } 

    void query (int now, int l, int r, int L, int R) {
        if (R < l || r < L)return;
        if (L <= l && r <= R) {
            res += tree[now];
            res %= qy; return;
        }
        if (lazy[now])pushdown (now, l, r);
        int mid = (l+r) >> 1;
        query (now << 1, l, mid, L, R);
        query (now << 1 | 1, mid+1, r, L, R);
    }

}using namespace segtree;

namespace tree_split {

    inline void MR (int x, int y, int change) {
        change %= qy;
        while (top[x] != top[y]) {
            if (depth[top[x]] < depth[top[y]])swap (x, y);
            update (1, 1, n, id[top[x]], id[x], change);
            x = father[top[x]];
        }
        if (depth[x] > depth[y])swap (x, y);
        update (1, 1, n, id[x], id[y], change);
    }

    inline void QR (int x, int y) {
        while (top[x] != top[y]) {
            if (depth[top[x]] < depth[top[y]])swap (x, y);
            res = 0;
            query (1, 1, n, id[top[x]], id[x]);
            ans += res; ans %= qy;
            x = father[top[x]];
        }
        if (depth[x] > depth[y])swap (x, y);
        res = 0;
        query (1, 1, n, id[x], id[y]);
        ans += res; ans %= qy;
    }

    inline void MT (int x, int change) {
        change %= qy;
        update (1, 1, n, id[x], id[x] + size[x] - 1, change);
    }

    inline void QT (int x) {
        res = 0;
        query (1, 1, n, id[x], id[x] + size[x] - 1);
        ans = res;
    }

    void DFS1 (int now, int fa, int d) {
        father[now] = fa;
        depth[now] = d;
        size[now] = 1;
        int maxson = -1;
        cross (i, now) {
            int v = edge[i].to;
            if (v == fa)continue;
            DFS1 (v, now, d+1);
            size[now] += size[v];
            if (size[v] > maxson) {
                maxson = size[v];
                son[now] = v;
            }
        }
    }

    void DFS2 (int now, int top_heavy) {
        top[now] = top_heavy;
        id[now] = ++dfn;
        rk[dfn] = now;
        if (! son[now])return;
        DFS2 (son[now], top_heavy);
        cross (i, now) {
            int v = edge[i].to;
            if (v != father[now] && v != son[now])DFS2 (v,v);
        }
    }

}using namespace tree_split;

signed main () {
 	read (n), read (q), read (root), read (qy);
 	rep (i, 1, n) read (a[i]);
 	rep (i, 1, n-1) {
 		int x, y; read (x), read (y);
 		connect (x, y), connect (y, x);
 	}
 	DFS1 (root, 0, 1); DFS2 (root, root);
 	build (1, 1, n);
 	rep (i, 1, q) {
 		int type, l, r, x; read (type);
 		if (type == 1) {
 			read (l), read (r), read (x);
 			MR (l, r, x);
 		}
 		if (type == 2) {
 			read (l), read (r); ans = 0;
 			QR (l, r); printf ("%lld\n", ans);
 		}
 		if (type == 3) {
 			read (l), read (x);
 			MT (l, x);
 		}
 		if (type == 4) {
 			read (l); ans = 0;
 			QT (l); printf ("%lld\n", ans);
 		}
 	}
 	return 0;
}

splay

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#define MAXN 300000
#define INF 1 << 29
using namespace std;

int n, sz, root;

struct spaly {

    int size[MAXN], father[MAXN], son[MAXN][3], cnt[MAXN], val[MAXN];

    inline void maintain (int x) {
        size[x] = size[son[x][0]] + size[son[x][1]] + cnt[x];
    }
    
    inline void rotate (int x) {
        int y = father[x], z = father[y];
        int k = son[y][1] == x, kk = son[z][1] == y;
        son[z][kk] = x, father[x] = z,
        son[y][k] = son[x][k ^ 1], father[son[x][k ^ 1]] = y,
        son[x][k ^ 1] = y, father[y] = x,
        maintain (y), maintain (x);
    }
    
    inline void splay (int x, int goal) {
        while (father[x] != goal) {
            int y = father[x], z = father[y];
            if (z != goal)
                (son[y][1] == x) ^ (son[z][1] == y)
                    ? rotate (x) : rotate (y);
            rotate (x);
        }
        if (! goal) root = x;
    }
    
    inline void find (int x) {
        int now = root;
        while (son[now][x > val[now]] && val[now] != x)
            now = son[now][x > val[now]];
        splay (now, 0);
    }
    
    int Kth (int x, int rank) {
        if (son[x][0] && rank <= size[son[x][0]]) return Kth (son[x][0], rank);
        return (rank <= size[son[x][0]] + cnt[x])
            ? x : Kth (son[x][1], rank - size[son[x][0]] - cnt[x]);
    }
    
    inline int prev (int x) {
        int now = root, pre;
        while (now) {
            (val[now] < x)
                ? pre = now, now = son[now][1]
                : now = son[now][0];
        }
        return pre;
    }
    
    inline int succ (int x) {
        int now = root, nxt;
        while (now) {
            (val[now] > x)
                ? nxt = now, now = son[now][0]
                : now = son[now][1];
        }
        return nxt;
    }
    
    inline void del (int x) {
        int pre = prev (x), nxt = succ (x);
        splay (pre, 0), splay (nxt, pre);
        int pos = son[nxt][0];
        if (cnt[pos] > 1) cnt[pos]--, splay (pos, 0);
        else son[nxt][0] = 0;
    }
    
    inline void insert (int x) {
        int now = root, fa = 0;
        while (now && x != val[now]) fa = now, now = son[now][x > val[now]];
        if (now) cnt[now]++;
        else {
            now = ++sz;
            if (fa) son[fa][x > val[fa]] = now;
            son[now][0] = son[now][1] = 0;
            size[now] = cnt[now] = 1;
            val[now] = x, father[now] = fa;
        }
        splay (now, 0);
    }

}tree;

int main () {
    scanf ("%d", &n), tree.insert (INF), tree.insert (-INF);
    for (register int i = 1; i <= n; i++) {
        int opt, x; scanf ("%d%d", &opt, &x);
        if (opt == 1) tree.insert (x);
        if (opt == 2) tree.del (x);
        if (opt == 3) tree.find (x), printf ("%d\n", tree.size[tree.son[root][0]]);
        if (opt == 4) printf ("%d\n", tree.val[tree.Kth (root, x + 1)]);
        if (opt == 5) printf ("%d\n", tree.val[tree.prev (x)]);
        if (opt == 6) printf ("%d\n", tree.val[tree.succ (x)]);
    }
    return 0;
}

excrt

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <cmath>
#include <algorithm>
#define int long long
#define MAXN 200000
using namespace std;

int a[MAXN], b[MAXN], n, x, y;

inline int mul (int o, int u, int qy) {
    int p = 0;
    while (u) {
        if (u & 1) p = (p + o) % qy;
        o = (o << 1) % qy;
        u >>= 1;
    }
    return p;
}

int GCD (int a, int b) {
    if (! b) return a;
    return GCD (b, a % b);
}

void EXGCD (int a, int b, int &x, int &y) {
    if (! b) {
        x = 1; y = 0; return;
    }
    EXGCD (b, a % b, x, y);
    int tmp = x;
    x = y;
    y = tmp - a / b * y;
}

void EXCRT () {
    int LCM = b[1], ans = a[1];
    for (register int i = 2; i <= n; i++, x = 0, y = 0) {
        int k = ((a[i] - ans) % b[i] + b[i]) % b[i];
        int gcd = GCD (LCM, b[i]); if (k % gcd) return;
        EXGCD (LCM, b[i], x, y);
        x = mul (x, k / gcd, b[i]);
        ans += x * LCM;
        LCM *= b[i] / gcd;
        ans = (ans % LCM + LCM) % LCM;
    }
    printf ("%lld\n", ans);
}

signed main () {
    scanf ("%lld", &n);
    for (register int i = 1; i <= n; i++) scanf ("%lld%lld", &b[i], &a[i]);
    EXCRT ();
    return 0;
}

树状数组套主席

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#define MAXN 100010
using namespace std;

struct ques {
    int a, b, c;
}q[MAXN];

int val[MAXN * 400], L[MAXN * 400], R[MAXN * 400], x[MAXN], y[MAXN];
int a[MAXN], b[MAXN << 1], root[MAXN], n, m, totx, toty, sz, tot;

inline int read () {
    register int s = 0, w = 1;
    register char ch = getchar ();
    while (! isdigit (ch)) {if (ch == '-') w = -1; ch = getchar ();}
    while (isdigit (ch)) {s = (s << 3) + (s << 1) + (ch ^ 48); ch = getchar ();}
    return s * w;
}

inline int lowbit (int x) {return x & (-x);}

void insert (int &o, int l, int r, int from, int x, int v) {
    o = ++sz, val[o] = val[from] + v,
    L[o] = L[from], R[o] = R[from];
    if (l == r) return;
    int mid = l + r >> 1;
    if (x <= mid) insert (L[o], l, mid, L[from], x, v);
    else insert (R[o], mid + 1, r, R[from], x, v);
}

inline void add (int x, int v) {
    int pos = lower_bound (b + 1, b + tot + 1, a[x]) - b;
    for (register int i = x; i <= n; i += lowbit (i))
        insert (root[i], 1, tot, root[i], pos, v);
}

int query (int o, int l, int r) {
    if (l == r) return r;
    int sum = 0, mid = l + r >> 1;
    for (register int i = 1; i <= totx; i++) sum -= val[L[x[i]]];
    for (register int i = 1; i <= toty; i++) sum += val[L[y[i]]];
    if (o <= sum) {
        for (register int i = 1; i <= totx; i++) x[i] = L[x[i]];
        for (register int i = 1; i <= toty; i++) y[i] = L[y[i]];
        return query (o, l, mid);
    }
    else {
        for (register int i = 1; i <= totx; i++) x[i] = R[x[i]];
        for (register int i = 1; i <= toty; i++) y[i] = R[y[i]];
        return query (o - sum, mid + 1, r);
    }
}

int main () {
    n = read (), m = read ();
    for (register int i = 1; i <= n; i++) a[i] = b[++tot] = read ();
    for (register int i = 1; i <= m; i++) {
        char opt[5]; scanf ("%s", opt);
        if (opt[0] == 'Q') q[i].a = read (), q[i].b = read (), q[i].c = read ();
        if (opt[0] == 'C') q[i].a = read (), q[i].b = b[++tot] = read ();
    }
    sort (b + 1, b + tot + 1);
    tot = unique (b + 1, b + tot + 1) - b - 1;
    for (register int i = 1; i <= n; i++) add (i, 1);
    for (register int i = 1; i <= m; i++, totx = 0, toty = 0)
        if (q[i].c) {
            for (register int j = q[i].a - 1; j; j -= lowbit (j)) x[++totx] = root[j];
            for (register int j = q[i].b; j; j -= lowbit (j)) y[++toty] = root[j];
            printf ("%d\n", b[query (q[i].c, 1, tot)]);
        }
        else add (q[i].a, -1), a[q[i].a] = q[i].b, add (q[i].a, 1);
    return 0;
}

割点

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#define MAXN 300000
using namespace std;

struct fls {
    int to, next;
}edge[MAXN << 1];

int head[MAXN << 1], low[MAXN], dfn[MAXN], cut[MAXN], idx, cnt, ans, n, m;

inline void connect (int u, int v) {
    edge[++cnt].to = v;
    edge[cnt].next = head[u];
    head[u] = cnt;
}

void tarjan (int now, int root) {
    dfn[now] = low[now] = ++idx; int sz = 0;
    for (register int i = head[now]; i; i = edge[i].next) {
        int v = edge[i].to;
        if (! dfn[v]) {
            tarjan (v, root);
            low[now] = min (low[now], low[v]);
            if (low[v] >= dfn[now] && now != root) cut[now] = 1;
            if (now == root) sz++;
        }
        low[now] = min (low[now], dfn[v]);
    }
    if (sz >= 2 && now == root) cut[now] = 1;
}

int main () {
    scanf ("%d%d", &n, &m);
    for (register int i = 1; i <= m; i++) {
        int x, y; scanf ("%d%d", &x, &y);
        connect (x, y), connect (y, x);
    }
    for (register int i = 1; i <= n; i++)
        if (! dfn[i]) tarjan (i, i);
    for (register int i = 1; i <= n; i++)
        if (cut[i]) ans++;
    printf ("%d\n", ans);
    for (register int i = 1; i <= n; i++)
        if (cut[i]) printf ("%d ", i);
}

缩点

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define MAXN 200000
using namespace std;

struct Front_Link_Star{
    int from,to,next;
}edge[MAXN],upd_edge[MAXN];

int head[MAXN],Stack[MAXN],dfn[MAXN],low[MAXN],top,sd[MAXN],n,m,upd_cnt;
int upd_head[MAXN],dist[MAXN],cnt,tag,indegree[MAXN],val[MAXN];
bool vis[MAXN];

inline void Add_Edge(int u,int v){
    edge[++cnt].next=head[u];
    edge[cnt].from=u;
    edge[cnt].to=v;
    head[u]=cnt;
}

inline int read(){
    int s=0,w=1;
    char ch=getchar();
    while (ch<'0'||ch>'9'){if (ch=='-')w=-1;ch=getchar();}
    while (ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getchar();}
    return s*w;
}

inline void tarjan(int now){
    dfn[now]=low[now]=++tag;
    vis[now]=1;Stack[++top]=now;
    for (register int i=head[now];i;i=edge[i].next){
        int v=edge[i].to;
        if (!dfn[v]){
            tarjan(v);
            low[now]=min(low[now],low[v]);
        }else if (vis[v])low[now]=min(low[now],low[v]);
    }
    if (dfn[now]==low[now])
        while (int y=Stack[top--]){
            sd[y]=now;vis[y]=0;
            if (now==y)break;
            val[now]+=val[y];
        }
}

int main(){
    n=read();m=read();
    for (register int i=1;i<=n;i++)
        val[i]=read();
    for (register int i=1;i<=m;i++){
    	int x=read(),y=read();
    	Add_Edge(x,y);
    }
    for (register int i=1;i<=n;i++)
        if (!dfn[i])tarjan(i);
    return 0;
}

kmp

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#define MAXN 1000400
using namespace std;

char a[MAXN], b[MAXN];
int fail[MAXN], la, lb, n;

int main () {
    scanf ("%s", a + 1), scanf ("%s", b + 1);
    la = strlen (a + 1), lb = strlen (b + 1);
    for (register int i = 2, j = 0; i <= lb; i++) {
        while (j && b[i] != b[j + 1]) j = fail[j];
        if (b[i] == b[j + 1]) j++; fail[i] = j;
    }
    for (register int i = 1, j = 0; i <= la; i++) {
        while (j && a[i] != b[j + 1]) j = fail[j];
        if (a[i] == b[j + 1]) j++;
        if (j == lb) printf ("%d\n", i - lb + 1), j = fail[j];
    }
    for (register int i = 1; i <= lb; i++) printf ("%d ", fail[i]);
    return 0;
}

高斯消元

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <cmath>
#include <algorithm>
#define MAXN 300
using namespace std;

double mat[MAXN][MAXN], ans[MAXN];
int n;

int main () {
    scanf ("%d", &n);
    for (register int i = 1; i <= n; i++)
        for (register int j = 1; j <= n + 1; j++)
            scanf ("%lf", &mat[i][j]);
    for (register int i = 1; i <= n; i++) {
        int pos = i;
        for (register int j = i + 1; j <= n; j++)
            if (fabs (mat[pos][i]) < fabs (mat[j][i])) pos = j;
        if (fabs (mat[pos][i]) < 1e-8) {
            puts ("No Solution");
            return 0;
        }
        swap (mat[pos], mat[i]);
        for (register int j = i + 1; j <= n; j++) {
            double alpha = mat[i][i] / mat[j][i];
            mat[j][i] = 0;
            for (register int k = i + 1; k <= n + 1; k++)
                mat[j][k] *= alpha, mat[j][k] -= mat[i][k];
        }
    }
    for (register int i = n; i >= 1; i--) {
        ans[i] = mat[i][n + 1];
        for (register int j = n; j >= 1; j--)
            if (i != j) ans[i] -= ans[j] * mat[i][j];
        ans[i] /= mat[i][i];
    }
    for (register int i = 1; i <= n; i++) printf ("%.2lf\n", ans[i]);
    return 0;
}

主席树

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#define MAXN 400000
#define read(a) a = slowread <int> ()
using namespace std;

int root[MAXN], a[MAXN], b[MAXN], n, m, cnt, newsize;

template <typename T> inline T slowread () {
    register int s = 0, w = 1;
    register char ch = getchar ();
    while (! isdigit (ch)) {if (ch == '-') w = -1; ch = getchar ();}
    while (isdigit (ch)) {s = (s << 3) + (s << 1) + (ch ^ 48); ch = getchar ();}
    return s * w;
}

struct chairtree {
    
    #define mid ((l + r) >> 1)
    
    int L[MAXN*40], R[MAXN*40], size[MAXN*40];
    
    void build (int &now, int l, int r) {
        now = ++cnt;
        if (l == r) return;
        build (L[now], l, mid);
        build (R[now], mid + 1, r);
    }
    
    int update (int from, int l, int r, int change) {
        int now = ++cnt; L[now] = L[from], R[now] = R[from], size[now] = size[from] + 1;
        if (l == r) return now;
        (change <= mid)
        ? L[now] = update (L[now], l, mid, change)
        : R[now] = update (R[now], mid + 1, r, change);
        return now;
    }
    
    int kth (int tl, int tr, int l, int r, int rank) {
        if (l == r) return l; int delta = size[L[tr]] - size[L[tl]];
        return (rank <= delta)
        ? kth (L[tl], L[tr], l, mid, rank)
        : kth (R[tl], R[tr], mid + 1, r, rank - delta);
    }
    
}tree;

int main () {
    read (n), read (m);
    for (register int i = 1; i <= n; i++) read (a[i]), b[i] = a[i];
    sort (b + 1, b + n + 1); newsize = unique (b + 1, b + n + 1) - (b + 1);
    tree.build (root[0], 1, newsize);
    for (register int i = 1; i <= n; i++) {
        int pos = lower_bound (b + 1, b + newsize + 1, a[i]) - b;
        root[i] = tree.update (root[i - 1], 1, newsize, pos);
    }
    for (register int i = 1; i <= m; i++) {
        int l, r, k; read (l), read (r), read (k);
        int pos = tree.kth (root[l-1], root[r], 1, newsize, k);
        printf ("%d\n", b[pos]);
    }
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值