感觉前上一篇的内容有些太多了,剩下的放在这里吧。
小椛椛的板子们 <- 这是上一篇
二分图匹配
#include <cstdio> #include <iostream> #include <queue> #include <cstring> #define INF 1e9 #define rg register #define Max 100008 const int BUF = 12312313; char Buf[BUF], *buf = Buf; inline void read (int &n) { for (n = 0; !isdigit (*buf); ++ buf); for (; isdigit (*buf); n = n * 10 + *buf - '0', ++ buf); } inline int min (int a, int b) { return a < b ? a : b; } int _v[Max << 5], _n[Max << 5], _f[Max << 5], list[Max], C = 1, d[Max], S, T, _th[Max]; int Flowing (int n, int f) { if (f <= 0 || n == T) return f; int r = 0, p, v; for (int &i = _th[n]; i; i = _n[i]) { if (!_f[i] || d[v = _v[i]] != d[n] + 1) continue; p = Flowing (v, min (_f[i], f)); _f[i ^ 1] += p, _f[i] -= p, r += p, f -= p; if (f <= 0) return r; } if (r != f) d[n] = -1; return r; } bool Bfs () { std :: queue <int> Q; Q.push (S); rg int n, i, v; memset (d, -1, sizeof d); d[S] = 0; for (; !Q.empty (); Q.pop ()) for (n = Q.front (), i = list[n]; i; i = _n[i]) if (_f[i] && d[v = _v[i]] < 0) { d[v] = d[n] + 1; if (v == T) return true; Q.push (v); } return d[T] != -1; } inline void In (int x, int y) { _v[++ C] = y, _n[C] = list[x], list[x] = C, _f[C] = 1; _v[++ C] = x, _n[C] = list[y], list[y] = C; } int main (int argc, char *argv[]) { fread (buf, 1, BUF, stdin); int N, M, E, x, y, s = 0; read (N), read (M), read (E); rg int i, j; for (i = 1, T = M + N + 1; i <= E; ++ i) { read (x), read (y); if (x > M || y > M) continue; In (x, y + N); } for (i = 1; i <= N; ++ i) In (S, i); for (i = 1; i <= M; ++ i) In (N + i, T); for (; Bfs (); ) { for (i = 0; i <= T; ++ i) _th[i] = list[i]; s += Flowing (S, INF); } printf ("%d", s); return 0; }
平衡树
二次联通门 : 数组splay ------ luogu P3369 【模板】普通平衡树(Treap/SBT)
二次联通门 : 指针splay ------ LibreOJ #107. 维护全序集
二次联通门 : 替罪羊树 ------ luogu P3369 【模板】普通平衡树(Treap/SBT)
二次联通门 : 红黑树 ------ luogu P3369 【模板】普通平衡树(Treap/SBT)
二次联通门 : fhq treap ------ luogu P3369 【模板】普通平衡树(Treap/SBT)
二逼平衡树
#include <cstdio> #define Max 4000005 #define INF 1e9 void read (int &now) { register char word = getchar (); int temp = 0; for (now = 0; word < '0' || word > '9'; word = getchar ()) if (word == '-') temp = 1; for (; word >= '0' && word <= '9'; now = now * 10 + word - '0', word = getchar ()); if (temp) now = -now; } int data[Max]; struct S_D { S_D *child[2], *father; int size, weigth; int key; S_D () { this->child[0] = this->child[1] = NULL; this->father = NULL; this->size = this->weigth = 1; this->key = 0; } void Clear () { this->child[0] = this->child[1] = NULL; this->father = NULL; } int Get_Pos () { return this->father->child[1] == this; } inline void Updata () { this->size = this->weigth; if (this->child[0]) this->size += this->child[0]->size; if (this->child[1]) this->size += this->child[1]->size; } }; int Maxn = -INF; inline int max (int a, int b) { return a > b ? a : b; } inline int min (int a, int b) { return a < b ? a : b; } struct X_D { X_D *Left, *Right; int l, r; int Mid; X_D (int __l, int __r) : l (__l), r (__r) { Left = Right = NULL; Mid = __l + __r >> 1; } }; int Answer; class Splay_Tree_Type { private : S_D *Root; void Rotate (S_D *now) { S_D *Father = now->father; int pos = now->Get_Pos () ^ 1; Father->child[pos ^ 1] = now->child[pos]; if (now->child[pos]) now->child[pos]->father = Father; if ((now->father = Father->father) != NULL) now->father->child[now->father->child[1] == Father] = now; Father->father = now; now->child[pos] = Father; Father->Updata (); now->Updata (); } void Splay (S_D *now) { for (S_D *Father; Father = now->father; this->Rotate (now)) if (Father->father) this->Rotate (now->Get_Pos () == Father->Get_Pos () ? Father : now); } public : void Insert (int x) { if (Root == NULL) { Root = new S_D ; Root->key = x; return ; } S_D *now = Root, *Father; for (; ; Father = now, now = now->child[x > now->key]) { if (now == NULL) { now = new S_D; now->father = Father; now->key = x; Father->child[x > Father->key] = now; this->Splay (now); Root = now; return ; } if (now->key == x) { now->weigth ++; this->Splay (now); Root = now; return ; } } } int Find_Rank (int x) { S_D *now = Root; int Answer = 0; for (; ; ) { if (now == NULL) return Answer; if (now->key == x) return (now->child[0] ? now->child[0]->size : 0) + Answer; else if (now->key < x) { Answer += (now->child[0] ? now->child[0]->size : 0) + now->weigth; now = now->child[1]; } else if (now->key > x) now = now->child[0]; } } void Find (int x) { S_D *now; for (now = Root; (now != NULL && x != now->key); now = now->child[x > now->key]); this->Splay (now); Root = now; return ; } void Delete () { S_D *now = Root; if (now->weigth > 1) { now->weigth --; now->size --; return ; } if (now->child[0] == NULL && now->child[1] == NULL) { Root = NULL; now->Clear (); return ; } S_D *res; if (now->child[1] == NULL) { res = now; now->child[0]->father = NULL; Root = now->child[0]; res->Clear (); return ; } if (now->child[0] == NULL) { res = now; now->child[1]->father = NULL; Root = now->child[1]; res->Clear (); return ; } res = Root; S_D *res_pre = Find_Prefix_Pos (); this->Splay (res_pre); Root = res_pre; Root->child[1] = res->child[1]; res->child[1]->father = Root; res->Clear (); Root->Updata (); return; } S_D *Find_Prefix_Pos () { S_D *now = Root; for (now = now->child[0]; now->child[1]; now = now->child[1]); return now; } int Ask_Prefix (int x) { S_D *now = Root; for (; now;) { if (now->key < x) { if (Answer < now->key) Answer = now->key; now = now->child[1]; } else now = now->child[0]; } return Answer; } int Ask_Suffix (int x) { S_D *now = Root; for (; now; ) { if (now->key > x) { if (Answer > now->key) Answer = now->key; now = now->child[0]; } else now = now->child[1]; } return Answer; } }; Splay_Tree_Type Splay[Max]; class Segment_Tree_Type { private : X_D *Root; void __Build_ (X_D *&now, int l, int r) { now = new X_D (l, r); if (l == r) return ; __Build_ (now->Left, l, now->Mid); __Build_ (now->Right, now->Mid + 1, r); } void __Insert_ (X_D *&now, int pos, int x, int _in) { Splay[_in].Insert (x); if (now->l == now->r) return ; if (pos <= now->Mid) __Insert_ (now->Left, pos, x, _in << 1); else __Insert_ (now->Right, pos, x, _in << 1 | 1); } void __Query_Rank_ (X_D *&now, int l, int r, int k, int _in) { if (l <= now->l && now->r <= r) { Answer += Splay[_in].Find_Rank (k); return ; } if (l <= now->Mid) __Query_Rank_ (now->Left, l, r, k, _in << 1); if (now->Mid < r) __Query_Rank_ (now->Right, l, r, k, _in << 1 | 1); } void __Change_ (X_D *&now, int pos, int x, int _in) { Splay[_in].Find (data[pos]); Splay[_in].Delete (); Splay[_in].Insert (x); if (now->l == now->r) return ; if (pos <= now->Mid) __Change_ (now->Left, pos, x, _in << 1); else __Change_ (now->Right, pos, x, _in << 1 | 1); } void __Query_Prefix_ (X_D *&now, int l, int r, int x, int _in) { if (l <= now->l && now->r <= r) { Answer = max (Answer, Splay[_in].Ask_Prefix (x)); return ; } if (l <= now->Mid) __Query_Prefix_ (now->Left, l, r, x, _in << 1); if (now->Mid < r) __Query_Prefix_ (now->Right, l, r, x, _in << 1 | 1); } void __Query_Suffix_ (X_D *&now, int l, int r, int x, int _in) { if (l <= now->l && now->r <= r) { Answer = min (Answer, Splay[_in].Ask_Suffix (x)); return ; } if (l <= now->Mid) __Query_Suffix_ (now->Left, l, r, x, _in << 1); if (r > now->Mid) __Query_Suffix_ (now->Right, l, r, x, _in << 1 | 1); } public : void Build (int l, int r) { __Build_ (Root, l, r); return ; } void Insert (int pos, int x) { __Insert_ (Root, pos, x, 1); return ; } int Query_Suffix (int l, int r, int k) { Answer = INF; __Query_Suffix_ (Root, l, r, k, 1); return Answer; } int Query_kth_number (int l, int r, int x) { int L, R, Mid; for (L = 0, R = Maxn + 1, Mid; L != R; ) { Mid = L + R >> 1; Answer = 0; this->Query_Rank (l, r, Mid); if (Answer < x) L = Mid + 1; else R = Mid; } return L - 1; } int Query_Rank (int l, int r, int k) { Answer = 0; __Query_Rank_(Root, l, r, k, 1); return Answer; } int Query_Prefix (int l, int r, int k) { Answer = 0; __Query_Prefix_ (Root, l, r, k, 1); return Answer; } void Change (int pos, int x) { __Change_ (Root, pos, x, 1); return ; } }; Segment_Tree_Type Seg; int main (int argc, char *argv[]) { int N, M; read (N); read (M); Seg.Build (1, N); for (int i = 1; i <= N; i ++) { read (data[i]); Maxn = max (data[i], Maxn); Seg.Insert (i, data[i]); } for (int type, x, y, z; M --; ) { read (type); if (type == 1) { read (x); read (y); read (z); printf ("%d ", Seg.Query_Rank (x, y, z) + 1); } else if (type == 2) { read (x); read (y); read (z); printf ("%d ", Seg.Query_kth_number (x, y, z)); } else if (type == 3) { read (x); read (z); Seg.Change (x, z); data[x] = z; Maxn = max (Maxn, x); } else if (type == 4) { read (x); read (y); read (z); printf ("%d ", Seg.Query_Prefix (x, y, z)); } else { read (x); read (y); read (z); printf ("%d ", Seg.Query_Suffix (x, y, z)); } } return 0; }