2018-12-29起,将各类模板都保存至此处。
(有错的话请各路神犇指教)
(所有代码经过vs2017格式整理)
1. 平衡树treap:
1 #include <cstdio> 2 #include <cstdlib> 3 const int maxn = 100005; 4 struct node 5 { 6 node *s[2]; 7 int k, f, siz; 8 node() {} 9 node(int w, node *son) 10 { 11 s[0] = s[1] = son; 12 k = w; 13 f = rand(); 14 siz = 1; 15 } 16 void pushup() 17 { 18 siz = s[0]->siz + s[1]->siz + 1; 19 } 20 } nil, base[maxn]; 21 typedef node *P_node; 22 P_node null, len, Root; 23 void treap_init() 24 { 25 nil = node(0, NULL); 26 null = &nil; 27 null->s[0] = null->s[1] = null; 28 null->siz = 0; 29 len = base; 30 Root = null; 31 } 32 P_node newnode(int x) 33 { 34 *len = node(x, null); 35 return len++; 36 } 37 P_node merge(P_node a, P_node b) 38 { 39 if (a == null) 40 return b; 41 if (b == null) 42 return a; 43 if (a->f > b->f) { 44 a->s[1] = merge(a->s[1], b); 45 a->pushup(); 46 return a; 47 } 48 b->s[0] = merge(a, b->s[0]); 49 b->pushup(); 50 return b; 51 } 52 void split(P_node x, int k, P_node &l, P_node &r) 53 { 54 if (x == null) 55 { 56 l = r = null; 57 return; 58 } 59 if (x->k <= k) 60 { 61 l = x; 62 split(l->s[1], k, l->s[1], r); 63 } 64 else 65 { 66 r = x; 67 split(r->s[0], k, l, r->s[0]); 68 } 69 x->pushup(); 70 } 71 void Insert(int k) 72 { 73 P_node l, r; 74 split(Root, k, l, r); 75 Root = merge(merge(l, newnode(k)), r); 76 } 77 void Erase(int k) 78 { 79 P_node l, mid, r; 80 split(Root, k - 1, l, r); 81 split(r, k, mid, r); 82 Root = merge(l, merge(merge(mid->s[0], mid->s[1]), r)); 83 } 84 int Kth(P_node x, int k) 85 { 86 if (k <= x->s[0]->siz) 87 return Kth(x->s[0], k); 88 else if (k > x->s[0]->siz + 1) 89 return Kth(x->s[1], k - x->s[0]->siz - 1); 90 return x->k; 91 } 92 int get_edge(P_node x, int d) 93 { 94 while (x->s[d] != null) x = x->s[d]; 95 return x->k; 96 } 97 int q; 98 inline int red() 99 { 100 int tot = 0, f = 1; 101 char ch = getchar(); 102 while (ch < '0' || '9' < ch) 103 { 104 if (ch == '-') 105 f = -f; 106 ch = getchar(); 107 } 108 while ('0' <= ch && ch <= '9') tot = tot * 10 + ch - 48, ch = getchar(); 109 return tot * f; 110 } 111 int main() 112 { 113 treap_init(); 114 q = red(); 115 while (q--) 116 { 117 int c = red(); 118 if (c == 1) 119 Insert(red()); 120 else if (c == 2) 121 Erase(red()); 122 else if (c == 3) 123 { 124 int k = red(); 125 P_node l, r; 126 split(Root, k - 1, l, r); 127 printf("%d\n", l->siz + 1); 128 Root = merge(l, r); 129 } 130 else if (c == 4) 131 printf("%d\n", Kth(Root, red())); 132 else if (c == 5) 133 { 134 int k = red(); 135 P_node l, r; 136 split(Root, k - 1, l, r); 137 printf("%d\n", get_edge(l, 1)); 138 Root = merge(l, r); 139 } 140 else 141 { 142 int k = red(); 143 P_node l, r; 144 split(Root, k, l, r); 145 printf("%d\n", get_edge(r, 0)); 146 Root = merge(l, r); 147 } 148 } 149 return 0; 150 }
2. 线段树(带lazy标记)
1 #include<iostream> 2 #include<cstdio> 3 #define MAXN 1000001 4 #define ll long long 5 using namespace std; 6 unsigned ll n, m, a[MAXN], ans[MAXN << 2], tag[MAXN << 2]; 7 inline ll ls(ll x) 8 { 9 return x << 1; 10 } 11 inline ll rs(ll x) 12 { 13 return x << 1 | 1; 14 } 15 void scan() 16 { 17 cin >> n >> m; 18 for (ll i = 1; i <= n; i++) 19 scanf("%lld", &a[i]); 20 } 21 inline void push_up(ll p) 22 { 23 ans[p] = ans[ls(p)] + ans[rs(p)]; 24 } 25 void build(ll p, ll l, ll r) 26 { 27 tag[p] = 0; 28 if (l == r) { ans[p] = a[l]; return; } 29 ll mid = (l + r) >> 1; 30 build(ls(p), l, mid); 31 build(rs(p), mid + 1, r); 32 push_up(p); 33 } 34 inline void f(ll p, ll l, ll r, ll k) 35 { 36 tag[p] = tag[p] + k; 37 ans[p] = ans[p] + k * (r - l + 1); 38 } 39 inline void push_down(ll p, ll l, ll r) 40 { 41 ll mid = (l + r) >> 1; 42 f(ls(p), l, mid, tag[p]); 43 f(rs(p), mid + 1, r, tag[p]); 44 tag[p] = 0; 45 } 46 inline void update(ll nl, ll nr, ll l, ll r, ll p, ll k) 47 { 48 if (nl <= l && r <= nr) 49 { 50 ans[p] += k * (r - l + 1); 51 tag[p] += k; 52 return; 53 } 54 push_down(p, l, r); 55 ll mid = (l + r) >> 1; 56 if (nl <= mid)update(nl, nr, l, mid, ls(p), k); 57 if (nr > mid) update(nl, nr, mid + 1, r, rs(p), k); 58 push_up(p); 59 } 60 ll query(ll q_x, ll q_y, ll l, ll r, ll p) 61 { 62 ll res = 0; 63 if (q_x <= l && r <= q_y)return ans[p]; 64 ll mid = (l + r) >> 1; 65 push_down(p, l, r); 66 if (q_x <= mid)res += query(q_x, q_y, l, mid, ls(p)); 67 if (q_y > mid) res += query(q_x, q_y, mid + 1, r, rs(p)); 68 return res; 69 } 70 int main() 71 { 72 ll a1, b, c, d, e, f; 73 scan(); 74 build(1, 1, n); 75 while (m--) 76 { 77 scanf("%lld", &a1); 78 switch (a1) 79 { 80 case 1: { 81 scanf("%lld%lld%lld", &b, &c, &d); 82 update(b, c, 1, n, 1, d); 83 break; 84 } 85 case 2: { 86 scanf("%lld%lld", &e, &f); 87 printf("%lld\n", query(e, f, 1, n, 1)); 88 break; 89 } 90 } 91 } 92 return 0; 93 }
3. 并查集
#include<iostream> using namespace std; const int N = 10000; int n, m; int fa[N], size[N]; inline void init() { for (int i = 1; i <= n; i++)fa[i] = i, size[i] = 1; } inline int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); } inline void merge(int x, int y) { int xx = find(x), yy = find(y); if (size[xx] < size[yy])swap(xx, yy); fa[yy] = xx; size[xx] += size[yy]; } inline bool both(int x, int y) { if (find(x) == find(y)) return 1; else return 0; } int main() { cin >> n >> m; init(); for (int i = 1; i <= m; i++) { int a, b, tmp; cin >> tmp; if (tmp == 1) { cin >> a >> b; merge(a, b); } if (tmp == 2) { cin >> a >> b; if (both(a, b)) cout << 'Y' << endl; else cout << 'N' << endl; } } return 0; }
4. 快速排序(sort也不错)
#include<bits/stdc++.h> using namespace std; void qsort(int, int); int a[100001], sum; int main() { int n, i; cin >> n; for (i = 1; i <= n; i++) cin >> a[i]; qsort(1, n); for (i = 1; i <= n; i++) cout << a[i] << " "; cout << endl; } void qsort(int l, int r) { int i, j, mid, p; i = l; j = r; mid = a[(l + r) / 2]; do { while (a[i] < mid) i++; while (a[j] > mid) j--; if (i <= j) { p = a[i]; a[i] = a[j]; a[j] = p; sum++; i++; j--; } } while (i <= j); if (l < j) qsort(l, j); if (i < r) qsort(i, r); }
5. 树剖
#include <cstdio> #include <algorithm> #include <cctype> using namespace std; #define rint register int #define mem(a,b) memset(a,(b),sizeof(a)) #define temp template<typename T> typedef long long LL; temp inline void read(T &x) { x = 0; T w = 1, ch = getchar(); while (!isdigit(ch) && ch != '-') ch = getchar(); if (ch == '-') w = -1, ch = getchar(); while (isdigit(ch)) { x = (x << 3) + (x << 1) + (ch^'0'); ch = getchar(); } x = x * w; } #define mid ((l+r)>>1) #define lson rt<<1,l,mid #define rson rt<<1|1,mid+1,r #define len (r-l+1) const int maxn = 200000 + 10; int n, m, r, mod; int e, beg[maxn], nex[maxn], to[maxn], w[maxn], wt[maxn]; int a[maxn << 2], laz[maxn << 2]; int son[maxn], id[maxn], fa[maxn], cnt, dep[maxn], siz[maxn], top[maxn]; int res = 0; inline void add(int x, int y) { to[++e] = y; nex[e] = beg[x]; beg[x] = e; } inline void pushdown(int rt, int lenn) { laz[rt << 1] += laz[rt]; laz[rt << 1 | 1] += laz[rt]; a[rt << 1] += laz[rt] * (lenn - (lenn >> 1)); a[rt << 1 | 1] += laz[rt] * (lenn >> 1); a[rt << 1] %= mod; a[rt << 1 | 1] %= mod; laz[rt] = 0; } inline void build(int rt, int l, int r) { if (l == r) { a[rt] = wt[l]; if (a[rt] > mod) a[rt] %= mod; return; } build(lson); build(rson); a[rt] = (a[rt << 1] + a[rt << 1 | 1]) % mod; } inline void query(int rt, int l, int r, int L, int R) { if (L <= l && r <= R) { res += a[rt]; res %= mod; return; } else { if (laz[rt]) pushdown(rt, len); if (L <= mid) query(lson, L, R); if (R > mid) query(rson, L, R); } } inline void update(int rt, int l, int r, int L, int R, int k) { if (L <= l && r <= R) { laz[rt] += k; a[rt] += k * len; } else { if (laz[rt]) pushdown(rt, len); if (L <= mid) update(lson, L, R, k); if (R > mid) update(rson, L, R, k); a[rt] = (a[rt << 1] + a[rt << 1 | 1]) % mod; } } inline int qrange(int x, int y) { int ans = 0; while (top[x] != top[y]) { if (dep[top[x]] < dep[top[y]]) swap(x, y); res = 0; query(1, 1, n, id[top[x]], id[x]); ans += res; ans %= mod; x = fa[top[x]]; } if (dep[x] > dep[y]) swap(x, y); res = 0; query(1, 1, n, id[x], id[y]); ans += res; return ans %= mod; } inline void updrange(int x, int y, int k) { k %= mod; while (top[x] != top[y]) { if (dep[top[x]] < dep[top[y]]) swap(x, y); update(1, 1, n, id[top[x]], id[x], k); x = fa[top[x]]; } if (dep[x] > dep[y]) swap(x, y); update(1, 1, n, id[x], id[y], k); } inline int qson(int x) { res = 0; query(1, 1, n, id[x], id[x] + siz[x] - 1); return res; } inline void updson(int x, int k) { update(1, 1, n, id[x], id[x] + siz[x] - 1, k); } inline void dfs1(int x, int f, int deep) { dep[x] = deep; fa[x] = f; siz[x] = 1; int maxson = -1; for (rint i = beg[x]; i; i = nex[i]) { int y = to[i]; if (y == f) continue; dfs1(y, x, deep + 1); siz[x] += siz[y]; if (siz[x] > maxson) son[x] = y, maxson = siz[y]; } } inline void dfs2(int x, int topf) { id[x] = ++cnt; wt[cnt] = w[x]; top[x] = topf; if (!son[x]) return; dfs2(son[x], topf); for (rint i = beg[x]; i; i = nex[i]) { int y = to[i]; if (y == fa[x] || y == son[x]) continue; dfs2(y, y); } } int main() { read(n); read(m); read(r); read(mod); for (rint i = 1; i <= n; i++) read(w[i]); for (rint i = 1; i < n; i++) { int a, b; read(a); read(b); add(a, b); add(b, a); } dfs1(r, 0, 1); dfs2(r, r); build(1, 1, n); while (m--) { int k, x, y, z; read(k); if (k == 1) { read(x); read(y); read(z); updrange(x, y, z); } else if (k == 2) { read(x); read(y); printf("%d\n", qrange(x, y)); } else if (k == 3) { read(x); read(y); updson(x, y); } else { read(x); printf("%d\n", qson(x)); } } // getchar(); // getchar(); }