日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

模板-数据结构

發布時間:2025/3/15 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 模板-数据结构 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

數據結構相關模版, 可能有錯誤, 省選前持續更正中

重要的不是模版內容, 而是提供算法的實現思路.


#define M (L+R>>1)// 刪除標記線段樹 struct SegmentTree {int y1, y2;int sumv[maxn<<2], addv[maxn<<2];bool clr[maxn<<2];void init() {sumv[1] = addv[1] = 0;clr[1] = 1; // 刪除整棵樹}#define lc (o<<1)#define rc (o<<1^1)void update(int o) {sumv[o] = sumv[lc] + sumv[rc];}void pushdown(int o, int L, int R) {if(clr[o]) {sumv[lc] = sumv[rc] = addv[lc] = addv[rc] = 0;clr[lc] = clr[rc] = 1;clr[o] = 0;}if(addv[o]) {int& x = addv[o];addv[lc] += x;addv[rc] += x;sumv[lc] += (M-L+1) * x; // 讓子結點的標記立刻生效sumv[rc] += (R-M) * x;x = 0;}}void modify(int o, int L, int R) {if(y1 <= L && R <= y2) {addv[o]++;sumv[o] += (R-L+1); // 標記立刻生效} else {pushdown(o, L, R);if(y1 <= M) modify(lc, L, M);if(y2 > M) modify(rc, M+1, R);update(o);}}int query(int o, int L, int R) {if(y1 <= L && R <= y2) return sumv[o];pushdown(o, L, R);int ret = 0;if(y1 <= M) ret += query(lc, L, M);if(y2 > M) ret += query(rc, M+1, R);return ret;}#undef lc#undef rc };// 動態開點線段樹 struct DynamicSegmentTree {int n;int d, x, y1, y2;int maxv[maxn<<2], sumv[maxn<<2];#define lc lc[o]#define rc rc[o]void update(int o) {sumv[o] = sumv[lc] + sumv[rc];maxv[o] = max(maxv[lc], maxv[rc]);}void modify(int& o, int L, int R) {if(!o) o = ++n;if(L == R) maxv[o] = sumv[o] = d;else {if(x <= M) modify(lc, L, M);else modify(rc, M+1, R);update(o); // notice}}int query_sum(int o, int L, int R) {if(!o) return 0;if(y1 <= L && R <= y2) return sumv[o];int ret = 0;if(y1 <= M) ret += query_sum(lc, L, M);if(M < y2) ret += query_sum(rc, M + 1, R;return ret;}int query_max(int o, int L, int R, int y1, int y2) {if(!o) return 0;if(y1 <= L && R <= y2) return maxv[o];int ret = 0;if(y1 <= M) ret = max(ret, query_max(lc, L, M));if(M < y2) ret = max(ret, query_max(rc, M + 1, R));return ret;}#undef lc#undef rc };// 主席樹 struct FunctionalSegmentTree {int n;int d, k;int lc[maxn], rc[maxn], s[maxn];void build(int& x, int y, int L, int R) {x = ++n;lc[x] = lc[y]; rc[x] = rc[y];if(L == R) v[x] = v[y] + 1;else if(d <= T[M]) build(lc[x], lc[y], L, M);else build(rc[x], rc[y], M+1, R);s[x] = v[x] + s[lc[x]] + s[rc[x]]; // OR : s[x] = s[y] + 1}int query(int x, int y, int L, int R) {if(L == R) return T[L];int ls = s[lc[y]] - s[lc[x]];if(ls >= k) return query(lc[x], lc[y], L, M);k -= ls;return query(rc[x], rc[y], M+1, R);} };struct BIT {int n, c[maxn];void modify(int x, int d) {for(; x <= n; x += (x&-x)) c[x] += d;}int query(int x) {int ret = 0;for(; x; x -= (x&-x)) ret += c[x];return ret;}void clear(int x) {for(; x <= n; x += (x&-x)) c[x] = 0;} };struct UnionFindSet {int n, pa[maxn];void init() {for(int i = 1; i <= n; i++) pa[i] = i;}int find(int x) {return x == pa[x] ? x : (pa[x] = find(pa[x]));} };struct HASH {int n;int A[maxn], head[maxn], next[maxn], hash[maxn];void init() {n = 0;memset(A, 0, sizeof(A));memset(head, 0, sizeof(head));memset(next, 0, sizeof(next));memset(hash, 0, sizeof(hash));}bool find(int x) {int y = (x >= 0 ? x : -x) % maxn;if(!hash[y]) return 0;for(int i = head[y]; i; i = next[i]) if(A[i] == x) return 1;return 0;}void insert(int x) {int y = (x >= 0 ? x : -x) % maxn;hash[y] = 1; A[++n] = x;next[n] = head[y]; head[y] = n;} };struct TreeChain {int n;int s[maxn], tid[maxn], dep[maxn], son[maxn], top[maxn];void init() {dfs1(1, 1);dfs2(1, 1);}void dfs1(int x, int y) {s[x] = 1; dep[x] = dep[fa[x] = y] + 1;for(int i = 0; i < ch[x].size(); i++) {int z = ch[x][i];if(z == fa[x]) continue;dfs1(z, x);s[x] += s[z];if(s[z] > s[son[x]]) son[x] = z;}}void dfs2(int x, int y) {tid[x] = ++n; top[x] = y;if(son[x]) dfs2(son[x], y);for(int i = 0; i < ch[x].size(); i++) {int z = ch[x][i];if(z == fa[x] || z == son[x]) continue;dfs2(z, z);}}int query_sum(int x, int y) {int ret = 0, cx = c[x]; // 用多棵動態開點線段樹維護while(top[x] != top[y]) {if(dep[top[x]] < dep[top[y]]) swap(x, y);seg.y1 = tid[top[x]];seg.y2 = tid[x];ret += seg.query_sum(root[cx], 1, n);x = fa[top[x]];}if(dep[x] > dep[y]) swap(x, y);seg.y1 = tid[x];seg.y2 = tid[y];ret += query_sum(root[cx], 1, n);return ret;}int query_max(int x, int y) {int ret = 0, cx = c[x];while(top[x] != top[y]) {if(dep[top[x]] < dep[top[y]]) swap(x, y);seg.y1 = tid[top[x]];seg.y2 = tid[x];ret = max(ret, query_max(root[cx], 1, n)); // noticex = fa[top[x]];}if(dep[x] > dep[y]) swap(x, y);seg.y1 = tid[x];seg.y2 = tid[y];ret = max(ret, query_max(roots[cx], 1, n));return ret;} };struct Treap {int n;int s[maxn], r[maxn], ch[maxn][2];#define lc ch[o][0]#define rc ch[o][1]void update(int o) {s[o] = s[lc] + s[rc] + 1;}void rotate(int& o, int d) {int p = ch[o][d^1]; ch[o][d^1] = ch[p][d]; ch[p][d] = o;update(o); update(p); o = p;}void insert(int& o, int k) {if(!o) r[o = ++n] = rand(), s[o] = 1;else {s[o]++;int d = (k <= s[lc] ? 0 : 1);if(d == 1) k -= (s[lc] + 1);insert(ch[o][d], k);if(r[ch[o][d]] > r[o]) rotate(o, d^1);}}#undef lc#undef rc };// 維護數列 struct Splay {int ch[maxn][2];int s[maxn];bool rev[maxn];int n, m;int ch[maxn][2], id[maxn];int mls[maxn], mrs[maxn], maxs[maxn], s[maxn], rech[maxn], v[maxn], sumv[maxn];bool mdf[maxn], rev[maxn];#define lc ch[o][0]#define rc ch[o][1]void update(int o) {s[o] = s[lc] + s[rc] + 1;sumv[o] = sumv[lc] + sumv[rc] + v[o];maxs[o] = max(maxs[lc], maxs[rc]);maxs[o] = max(maxs[o], mrs[lc] + v[o] + mls[rc]);mls[o] = max(mls[lc], sumv[lc] + v[o] + mls[rc]);mrs[o] = max(mrs[rc], sumv[rc] + v[o] + mrs[lc]);}void pushdown(int o) {if(mdf[o]) {mdf[o] = rev[o] = 0;if(lc) mdf[lc] = 1, v[lc] = v[o], sumv[lc] = v[o]*s[lc];if(rc) mdf[rc] = 1, v[rc] = v[o], sumv[rc] = v[o]*s[rc];if(v[o] >= 0) {if(lc) mls[lc] = mrs[lc] = maxs[lc] = sumv[lc];if(rc) mls[rc] = mrs[rc] = maxs[rc] = sumv[rc];} else {if(lc) mls[lc] = mrs[lc] = 0, maxs[lc] = v[o];if(rc) mls[rc] = mrs[rc] = 0, maxs[rc] = v[o];}}if(rev[o]) {rev[o]^=1;rev[lc]^=1;rev[rc]^=1;swap(mls[lc], mrs[lc]);swap(mls[rc], mrs[rc]);swap(ch[lc][0], ch[lc][1]);swap(ch[rc][0], ch[rc][1]);}}void rotate(int& o, int d) {int p = ch[o][d^1]; ch[o][d^1] = ch[p][d]; ch[p][d] = o;update(o); update(p); o = p;}int cmp(int o, int k) {if(s[lc] + 1 == k) return -1;return k < s[lc] + 1 ? 0 : 1;}void splay(int& o, int k) {pushdown(o);int d = cmp(o, k);if(d == -1) return;if(d == 1) k -= (s[lc] + 1);int p = ch[o][d];pushdown(p);int d2 = cmp(p, k);int k2 = (d2 == 0 ? k : k-s[ch[p][0]]-1);if(d2 != -1) {splay(ch[p][d2], k2);if(d == d2) rotate(o, d^1); else rotate(ch[o][d], d);}rotate(o, d^1);}void build(int& o, int L, int R) {if(L > R) return;o = (L+R)>>1;build(lc, L, o-1);build(rc, o+1, R);update(o);}void getInterval(int& o, int pos, int tot) {splay(o, pos);splay(rc, pos + tot - s[lc]);}// 用的時候改一下 int o, pos, tot, val;void insert() {getInterval(o, pos+1, 0);for(int i = n+1; i <= n+tot; i++) scanf("%d", &v[i]);build(ch[rc][0], n+1, n+tot);n += tot; //update(rc); update(o);}void remove() {getInterval(o, pos, tot);ch[rc][0] = 0;update(rc); update(o);}void modify() {getInterval(o, pos, tot);int p = ch[rc][0];v[p] = val;mdf[p] = 1;sumv[p] = v[p]*s[p];if(val >= 0) mls[p] = mrs[p] = maxs[p] = sumv[p];else mls[p] = mrs[p] = 0, maxs[p] = v[p]; // 規定 mls >= 0, mrs >= 0, 方便維護update(rc); update(o);}void rever() {getInterval(o, pos, tot);if(!mdf[o]) {int p = ch[rc][0];rev[p]^=1;swap(ch[p][0], ch[p][1]);swap(mls[p], mrs[p]);}update(rc); update(o);}void query() {getInterval(o, pos, tot);printf("%d\n", sumv[ch[rc][0]]);}#undef lc#undef rc };struct Splay {int s[maxn], ch[maxn][2];#define lc ch[o][0]#define rc ch[o][1]int kth(int o, int k) {if(s[lc] + 1 == k) return o;else if(s[lc] >= k) return kth(lc, k); else return kth(rc, k-s[lc]-1); }// 自底向上void rotate(int& o, int x) {int y = fa[x], z = fa[y];bool d = (ch[y][0] == x), d2 = (ch[z][0] == y);if(o == y) o = x; else ch[z][d2] = x;fa[x] = z; fa[y] = x; fa[ch[y][d] = ch[x][d^1]] = y;ch[x][d^1] = y; update(y); update(x);}void splay(int& o, int x) {while(o != x) {int y = fa[x], z = fa[y]; if(o != y)if(ch[y][0] == x^ch[z][0] == y) rotate(o, x); else rotate(o, y);rotate(o, x);}}void remove(int& o, int k) {int p = kth(o, k-1), q = kth(o, k+1); splay(o, p); splay(rc, q);int t = ch[q][0]; ch[q][0] = 0; fa[t] = s[t] = 0;update(q); update(p);}#undef lc#undef rc };// 線段樹的功能 struct Splay {int s[maxn], ch[maxn][2];lli v[maxn], sumv[maxn], inc[maxn];#define lc ch[o][0]#define rc ch[o][1]#define seq ch[rc][0]void update(int o) {s[o] = s[lc] + s[rc] + 1;sumv[o] = sumv[lc] + sumv[rc] + v[o];}void pushdown(int o) {if(!inc[o]) return;inc[lc] += inc[o]; v[lc] += inc[o]; sumv[lc] += inc[o] * s[lc];inc[rc] += inc[o]; v[rc] += inc[o]; sumv[rc] += inc[o] * s[rc];inc[o] = 0;}int cmp(int o, int k) {if(s[lc] + 1 == k) return -1;return k < s[lc] + 1 ? 0 : 1;}void rotate(int& o, int d) {int p = ch[o][d^1]; ch[o][d^1] = ch[p][d]; ch[p][d] = o;update(o); update(p); o = p;}void splay(int& o, int k) {pushdown(o); //int d = cmp(o, k);if(d == -1) return;if(d == 1) k -= (s[lc] + 1);int p = ch[o][d];pushdown(p); //int d2 = cmp(p, k);if(d2 != -1) {int k2 = (d2 == 0 ? k : k-s[ch[p][0]]-1);splay(ch[p][d2], k2);if(d == d2) rotate(o, d^1); else rotate(ch[o][d], d);}rotate(o, d^1);}void build(int& o, int L, int R) {if(L > R) return;o = (L+R)>>1;build(lc, L, o-1); build(rc, o+1, R);update(o);} };struct KMP {int n, m;int f[maxn];char P[maxn];void getFail() {f[0] = f[1] = 0;for(int i = 1; i < m; i++) { // 用 f[i] 推出 f[i+1]int j = f[i];while(j && P[i] != P[j]) j = f[j];f[i+1] = (P[i] == P[j] ? j+1 : 0);}}void find(char* T) {n = strlen(T), m = strlen(P);getFail();int j = 0;for(int i = 0; i < n; i++) {while(j && P[j] != T[i]) j = f[j];if(P[j] == T[i]) j++;if(j == m) { printf("%d\n", i-m+2); break; }}} };struct SuffixArray {int n;int s[maxn], sa[maxn], rank[maxn], height[maxn]int t[maxn], t2[maxn], c[maxn];void build_sa(int m) {int i, *x = t, *y = t2; // 加快交換時間// 基數排序for(i = 0; i < m; i++) c[i] = 0;for(i = 0; i < n; i++) c[x[i] = s[i]]++;for(i = 1; i < m; i++) c[i] += c[i-1];for(i = n-1; i >= 0; i--) sa[--c[x[i]]] = i;for(int k = 1; k <= n; k <<= 1) {int p = 0;for(i = n-k; i < n; i++) y[p++] = i;for(i = 0; i < n; i++) if(sa[i] >= k) y[p++] = sa[i]-k; // 用上次結果對第二關鍵字進行排序for(i = 0; i < m; i++) c[i] = 0;for(i = 0; i < n; i++) c[x[y[i]]]++;for(i = 0; i < m; i++) c[i] += c[i-1];for(i = n-1; i >= 0; i--) sa[--c[x[y[i]]]] = y[i];swap(x, y);p = 1;x[sa[0]] = 0;for(i = 1; i < n; i++)x[sa[i]] = y[sa[i-1]]==y[sa[i]] && y[sa[i-1]+k]==y[sa[i]+k] ? p-1 : p++;if(p >= n) break;m = p;}}void build_height() {int i, j, k = 0;for(i = 0; i < n; i++) rank[sa[i]] = i;for(i = 0; i < n; i++) {if(k) k--;int j = sa[rank[i]-1];while(s[i+k] == s[j+k]) k++;height[rank[i]] = k;}} };

總結

以上是生活随笔為你收集整理的模板-数据结构的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。