I will no longer be |

yabnto

园龄:2年8个月粉丝:14关注:17

平衡树板子

总览

  1. 长达146km的代码
  2. 长达134km的代码
  3. 长达88km的代码
  4. 这个是个 0
  5. 长达124cm的代码
  6. 长达126km的代码
  7. 长达93mm的代码
  8. 长达66um的代码

替罪羊

#include <algorithm>
#include <iostream>
using namespace std;
const int MaxN = 4e5 + 10;
const double eps = 0.75;
int d[MaxN], l[MaxN], r[MaxN], cnt[MaxN], sum[MaxN], sz[MaxN], a[MaxN], tot, n, root, len;
void update(int x) { // 更新
sum[x] = sum[l[x]] + sum[r[x]] + cnt[x];
sz[x] = sz[l[x]] + sz[r[x]] + 1;
}
bool Check(int x) { // 判断是否需要重构
return cnt[x] && 1.0 * max(sz[l[x]], sz[r[x]]) > eps * sz[x];
}
void dfs(int x) { // 中序遍历
if (!x) {
return;
}
dfs(l[x]);
cnt[x] && (a[++len] = x);
dfs(r[x]);
}
int build(int pl, int pr) { // 二分重构
if (pl > pr) {
return 0;
}
int mid = (pl + pr) >> 1;
l[a[mid]] = build(pl, mid - 1);
r[a[mid]] = build(mid + 1, pr);
update(a[mid]);
return a[mid];
}
int G(int k) {
len = 0;
dfs(k);
return k = build(1, len);
}
void insert(int &k, int x) { // 添加
if (!k) {
k = ++tot;
(!root) && (root = tot);
d[tot] = x, l[tot] = r[tot] = 0, sum[tot] = cnt[tot] = sz[tot] = 1;
return;
}
if (d[k] == x) {
cnt[k]++;
} else if (d[k] < x) {
insert(r[k], x);
} else {
insert(l[k], x);
}
update(k);
if (Check(k)) {
k = G(k);
}
}
void delet(int &k, int x) { // 删除
if (!k) {
return;
}
if (d[k] == x) {
cnt[k] && (cnt[k]--);
} else if (d[k] < x) {
delet(r[k], x);
} else {
delet(l[k], x);
}
update(k);
if (Check(k)) {
k = G(k);
}
}
int At(int k, int x) { // @
if (!k) {
return 0;
}
if (sum[l[k]] < x && x <= sum[l[k]] + cnt[k]) {
return d[k];
} else if (sum[l[k]] + cnt[k] < x) {
return At(r[k], x - sum[l[k]] - cnt[k]);
}
return At(l[k], x);
}
int upbd(int k, int x) { // 大于
if (!k) {
return 1;
}
if (d[k] == x && cnt[k]) {
return sum[l[k]] + cnt[k] + 1;
} else if (x < d[k]) {
return upbd(l[k], x);
}
return upbd(r[k], x) + sum[l[k]] + cnt[k];
}
int upgrt(int k, int x) { // 小于
if (!k) {
return 0;
}
if (d[k] == x && cnt[k]) {
return sum[l[k]];
} else if (d[k] < x) {
return upgrt(r[k], x) + sum[l[k]] + cnt[k];
}
return upgrt(l[k], x);
}
int p(int x) { // 前驱
return At(root, upgrt(root, x));
}
int h(int x) { // 后继
return At(root, upbd(root, x));
}
int main() {
cin >> n;
for (int op, x; n; n--) {
cin >> op >> x;
if (op == 1) {
insert(root, x);
} else if (op == 2) {
delet(root, x);
} else if (op == 3) {
cout << upgrt(root, x) + 1 << '\n';
} else if (op == 4) {
cout << At(root, x) << '\n';
} else if (op == 5) {
cout << p(x) << '\n';
} else {
cout << h(x) << '\n';
}
}
return 0;
}

旋转Treap

#include <ctime>
#include <iostream>
#include <random>
using namespace std;
const int MaxN = 1e5 + 10;
struct Node {
int d, v, l, r, sum, cnt;
} w[MaxN];
int n, root, tot;
void update(int x) {
w[x].sum = w[w[x].l].sum + w[w[x].r].sum + w[x].cnt;
}
void left(int &k) {
int p = w[k].l;
w[k].l = w[p].r, w[p].r = k, k = p;
update(w[k].r), update(k);
}
void right(int &k) {
int p = w[k].r;
w[k].r = w[p].l, w[p].l = k, k = p;
update(w[k].l), update(k);
}
void insert(int &k, int x) {
if (!k) {
k = ++tot;
w[k] = {x, rand(), 0, 0, 1, 1};
return;
}
if (w[k].d == x) {
w[k].cnt++;
} else if (w[k].d < x) {
insert(w[k].r, x);
if (w[w[k].r].v < w[k].v) {
right(k);
}
} else {
insert(w[k].l, x);
if (w[w[k].l].v < w[k].v) {
left(k);
}
}
update(k);
}
void delet(int &k, int x) {
if (!k) {
return;
}
if (w[k].d == x) {
if (w[k].cnt) {
w[k].cnt--, update(k);
} else if (w[k].l || w[k].r) {
if (!w[k].r || w[w[k].l].d > w[w[k].r].d) {
left(k), delet(w[k].l, x);
} else {
right(k), delet(w[k].r, x);
}
update(k);
} else {
k = 0;
}
}
if (w[k].d < x) {
delet(w[k].r, x);
} else {
delet(w[k].l, x);
}
update(k);
}
int upbd(int k, int x) {
if (!k) {
return 1;
}
if (w[k].d == x) {
return w[w[k].l].sum + w[k].cnt + 1;
} else if (w[k].d < x) {
return upbd(w[k].r, x) + w[w[k].l].sum + w[k].cnt;
}
return upbd(w[k].l, x);
}
int upgrt(int k, int x) {
if (!k) {
return 0;
}
if (w[k].d == x) {
return w[w[k].l].sum;
} else if (x < w[k].d) {
return upgrt(w[k].l, x);
}
return upgrt(w[k].r, x) + w[w[k].l].sum + w[k].cnt;
}
int At(int k, int x) {
if (!k) {
return 0;
}
if (w[w[k].l].sum < x && x <= w[w[k].l].sum + w[k].cnt) {
return w[k].d;
} else if (w[w[k].l].sum + w[k].cnt < x) {
return At(w[k].r, x - w[w[k].l].sum - w[k].cnt);
}
return At(w[k].l, x);
}
int main() {
srand(time(NULL));
cin >> n;
for (int op, x; n; n--) {
cin >> op >> x;
if (op == 1) {
insert(root, x);
} else if (op == 2) {
delet(root, x);
} else if (op == 3) {
cout << upgrt(root, x) + 1 << '\n';
} else if (op == 4) {
cout << At(root, x) << '\n';
} else if (op == 5) {
cout << At(root, upgrt(root, x)) << '\n';
} else {
cout << At(root, upbd(root, x)) << '\n';
}
}
return 0;
}

FHQ

#include <iostream>
#include <ctime>
using namespace std;
const int MaxN = 2e6 + 10;
struct S {
int x, v, ls, rs, sum;
} a[MaxN];
int rt, tot, t, n, ans;
int update(int k) {
return a[k].sum = k ? a[a[k].ls].sum + a[a[k].rs].sum + 1 : 0, k;
}
void split(int k, int v, int &x, int &y) {
if (!k) return;
int l = a[k].ls, r = a[k].rs;
((a[k].x <= v) ? (split(r, v, a[k].rs = 0, y), x) : (split(l, v, x, a[k].ls = 0), y)) = k;
update(k);
}
int merge(int x, int y) {
if (!x || !y) return x | y;
return update((a[x].v <= a[y].v) ? (a[x].rs = merge(a[x].rs, y), x) : (a[y].ls = merge(x, a[y].ls), y));
}
void insert(int v, int x = 0, int y = 0) {
split(rt, v, x, y);
a[++tot] = {v, rand(), 0, 0, 1};
rt = merge(merge(x, tot), y);
}
void delet(int &k, int x) {
if (a[k].x == x) {
k = merge(a[k].ls, a[k].rs);
} else {
a[k].x <= x ? delet(a[k].rs, x) : delet(a[k].ls, x);
update(k);
}
}
int upgrt(int k, int x) {
if (!k) return 0;
if (a[k].x >= x) {
return upgrt(a[k].ls, x);
}
return upgrt(a[k].rs, x) + a[a[k].ls].sum + 1;
}
int shit2(int k, int x) {
if (!k) return 0;
if (x == a[a[k].ls].sum + 1) {
return a[k].x;
} else if (a[a[k].ls].sum + 1 < x) {
return shit2(a[k].rs, x - a[a[k].ls].sum - 1);
}
return shit2(a[k].ls, x);
}
int main() {
ios::sync_with_stdio(0), cin.tie(0);
srand(time(NULL));
cin >> n >> t;
for (int i = 1, x; i <= n; i++) {
cin >> x, insert(x);
}
for (int op, x, lst = 0; t; t--) {
cin >> op >> x, x ^= lst;
if (op == 1) {
insert(x);
} else if (op == 2) {
delet(rt, x);
} else if (op == 3) {
ans ^= (lst = upgrt(rt, x) + 1);
} else if (op == 4) {
ans ^= (lst = shit2(rt, x));
} else if (op == 5) {
ans ^= (lst = shit2(rt, upgrt(rt, x)));
} else {
ans ^= (lst = shit2(rt, upgrt(rt, x + 1) + 1));
}
}
cout << ans << endl;
return 0;
}

平板电视 pb_ds

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/hash_policy.hpp>
#include <ext/pb_ds/priority_queue.hpp>
using namespace std;
using namespace __gnu_pbds;
typedef int pii;
void tree_test()
{
tree<pii,null_type,less<pii>,rb_tree_tag,tree_order_statistics_node_update> t,nt;
//可遍历: for(xx::iterator it=t.begin();it!=t.end();it++)
//一些正常的函数: t.clear(); t.empty(); t.find();
//插入: t.insert(x);
//所有元素不可重
//删除: t.erase(x);
//排名: t.order_of_key(x);
//返回【严格小于】x的数的个数
//kth: t.find_by_order(k);
//返回从小到大第k个数的iterator【从0开始】
//当k>=sz时返回t.end()
//lower_bound: t.lower_bound(x);
//*it>=x
//upper_bound: t.upper_bound(x);
//*it>x
//合并: t.join(nt);
//将nt合并进入t,之后nt清空
//t,nt需要类型相同,且值域不重合
//分裂: t.split(x,nt);
//将<=x的元素留在t中,其余放到nt中
//会将nt中原有元素扔掉
}
void priority_queue_test()
{
//小根堆greater<pii> 大根堆less<pii>
__gnu_pbds::priority_queue<pii,std::less<pii>,pairing_heap_tag> Q,nQ;
//可遍历: for(xx::iterator it=Q.begin();it!=Q.end();it++)
//遍历顺序与堆的性质相反
//基本函数: Q.push(x); Q.pop(); Q.top(); Q.clear(); Q.empty(); Q.size();
//合并: Q.join(nQ);
//会把nQ清空
}
void hash_test()
{
gp_hash_table<string,int> mp;
//可遍历: for(xx::iterator it=mp.begin();it!=mp.end();it++)
//it->first it->second
//【遍历顺序不按第一关键字】
//经典用法: mp["rlstxdy"]=666;
//基本函数: mp.size(); mp.empty();
}
int main()
{
tree_test();
hash_test();
priority_queue_test();
}

FHQ 进阶

#include <iostream>
#include <ctime>
using namespace std;
const int MaxN = 2e5 + 10;
struct tree {
struct S {
int w, v, l, r, sum, tag, fa;
char c; // __builtin_popcount
} a[MaxN];
int tot, root;
bool vis[MaxN];
int update(int k) {
(a[k].l) && (a[a[k].l].fa = k), (a[k].r) && (a[a[k].r].fa = k);
a[k].fa = 0;
return (k) && (a[k].sum = a[a[k].l].sum + a[a[k].r].sum + 1, a[k].w = a[a[k].l].w | a[a[k].r].w | (1 << (a[k].c - 'a'))), k;
}
void pd(int k) {
if (!a[k].tag) return;
swap(a[k].l, a[k].r);
a[a[k].l].tag ^= 1, a[a[k].r].tag ^= 1;
a[k].tag = 0;
}
int split(int k, int v, int &x, int &y, int l = 0, int r = 0) {
if (!k) return x = y = 0;
pd(k), l = a[k].l, r = a[k].r;
((a[l].sum + 1 <= v) ? (split(r, v - a[l].sum - 1, a[k].r = 0, y), x) : (split(l, v, x, a[k].l = 0), y)) = k;
return update(k);
}
int merge(int x, int y) {
if (!x || !y) return x | y;
return update((a[x].v < a[y].v) ? (pd(x), a[x].r = merge(a[x].r, y), x) : (pd(y), a[y].l = merge(x, a[y].l), y));
}
void insert(int id, char c, int s = 0, int b = 0) {
split(root, id, s, b);
a[++tot] = {(1 << (c - 'a')), rand(), 0, 0, 1, 0, 0, c};
root = merge(merge(s, tot), b), vis[tot] = 1;
}
void erase(int id, int k = 0, int y = 0, int n = 0) {
split(root, id - 1, k, n);
split(n, 1, y, n);
vis[y] = 0;
root = merge(k, n);
}
int query(int l, int r, int k = 0, int y = 0, int n = 0) {
split(root, r, k, n);
split(k, l - 1, k, y);
int res = a[y].w;
root = merge(merge(k, y), n);
return __builtin_popcount(res);
}
void reverse(int l, int r, int k = 0, int y = 0, int n = 0) {
split(root, r, k, n);
split(k, l - 1, k, y);
a[y].tag ^= 1;
root = merge(merge(k, y), n);
}
char At(int k, int x) {
if (!k) return 0;
pd(k);
if (a[a[k].l].sum + 1 < x) {
return At(a[k].r, x - a[a[k].l].sum - 1);
} else if (a[a[k].l].sum >= x) {
return At(a[k].l, x);
}
return a[k].c;
}
bool DFS(int x) {
if (!x) return 1;
DFS(a[x].fa), pd(x);
return 1;
}
int Gk(int k, bool flag = 1) {
if (!vis[k] || k == root) return 0;
(flag) && (DFS(k));
return Gk(a[k].fa, 0) + flag * (a[a[k].l].sum + 1) + (a[a[k].fa].r == k) * (a[a[a[k].fa].l].sum + 1);
}
} tr;
int n, m;
string s;
int main() {
srand(time(NULL));
cin >> n >> m >> s;
for (int i = 0; i < n; i++) {
tr.insert(i + 1, s[i]);
}
for (int x, y; m; m--) {
char op, c;
cin >> op >> x;
if (op == 'I') {
cin >> c;
tr.insert(x, c);
} else if (op == 'D') {
tr.erase(x);
} else if (op == 'R') {
cin >> y;
tr.reverse(x, y);
} else if (op == 'P') {
cout << tr.Gk(x) << endl;
} else if (op == 'T') {
cout << tr.At(tr.root, x) << endl;
} else {
cin >> y;
cout << tr.query(x, y) << endl;
}
}
return 0;
}

splay

#include <iostream>
using namespace std;
const int MaxN = 1e6 + 1e5 + 10;
struct Tree {
struct Node {
int w, ch[2], fa, cnt, sum, tag, x;
} a[MaxN];
int tot, root, l, r;
Node operator[](int k) {
return a[k];
}
void update(int k) {
a[k].sum = a[a[k].ch[0]].sum + a[a[k].ch[1]].sum + a[k].cnt;
}
void pushdown(int k) {
if (a[k].tag) {
swap(a[k].ch[0], a[k].ch[1]);
a[a[k].ch[1]].tag ^= 1;
a[a[k].ch[0]].tag ^= 1;
a[k].tag = 0;
}
}
void rotatr(int x) {
int y = a[x].fa, z = a[y].fa, k = a[y].ch[1] == x;
a[z].ch[y == a[z].ch[1]] = x, a[x].fa = z;
a[y].ch[k] = a[x].ch[k ^ 1], a[a[x].ch[k ^ 1]].fa = y;
a[x].ch[k ^ 1] = y, a[y].fa = x;
update(y);
}
void splay(int x, int to = 0) {
for (int y, z; a[x].fa != to; y = a[x].fa, z = a[y].fa, (z != to) ? (((y == a[z].ch[1]) ^ (x == a[y].ch[1])) ? rotatr(x) : rotatr(y)) : void(), rotatr(x)) {
}
update(x), (to) || (root = x);
}
int At(int x) {
int k = root;
if (!k) return k;
for (; (pushdown(k), a[k].ch[x > a[k].x]) && a[k].x != x; k = a[k].ch[x > a[k].x]) {
}
return splay(k), k;
}
void insert(int x) {
int k = root, y = 0;
for (; k && a[k].x != x; y = k, k = a[k].ch[x > a[k].x]) {
}
(k) ? (a[k].cnt++) : (k = ++tot, a[k] = {x, {0, 0}, y, 1, 1, 0, x}, (y) && (a[y].ch[x > a[y].x] = k));
splay(k);
}
Tree() {
root = tot = 0;
a[0] = {0, {0, 0}, 0, 0, 0, 0};
insert(-2e9), insert(2e9);
}
int kth(int x) {
int k = root;
for (int tx, kll; (pushdown(k), k) && !(a[a[k].ch[0]].sum < x && x <= a[a[k].ch[0]].sum + a[k].cnt); kll = a[k].cnt + a[a[k].ch[0]].sum, tx = x, (kll < tx) && (x -= kll), k = a[k].ch[kll < tx]) {
}
return splay(k), k;
}
int pn(int x, bool flag) { // 0 为前驱,1 为后继
At(x);
int k = root;
if (a[k].x > x && flag || a[k].x < x && !flag) return splay(k), k;
k = a[k].ch[flag];
for (; a[k].ch[!flag]; k = a[k].ch[!flag]) {
}
return splay(k), k;
}
void erase(int x) {
int pre = pn(x, 0), nxt = pn(x, 1);
splay(pre), splay(nxt, pre);
int k = a[nxt].ch[0];
if (a[k].cnt > 1) {
a[k].cnt--;
splay(k);
} else {
a[nxt].ch[0] = 0;
splay(nxt);
}
}
void reverse(int l, int r){
l = kth(l), r = kth(r + 2);
splay(l), splay(r, l);
a[a[r].ch[0]].tag ^= 1;
}
void DFS(int x) {
if (!x) return;
pushdown(x);
DFS(a[x].ch[0]);
if (a[x].x != -2e9 && a[x].x != 2e9) cout << a[x].x << " ";
DFS(a[x].ch[1]);
}
} tree;
int n, m, ans;
int main() {
ios::sync_with_stdio(0), cin.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; i++) {
tree.insert(i);
}
for (int i = 1, l, r; i <= m; i++) {
cin >> l >> r;
tree.reverse(l, r);
}
tree.DFS(tree.root);
return 0;
}

FHQ 进阶2

#include <iostream>
#include <ctime>
using namespace std;
const int MaxN = 2e5 + 10;
struct Tree {
struct Node {
int w, v, l, r, sum, tag;
} a[MaxN];
int root, tot;
int update(int k) {
return a[k].sum = k ? a[a[k].l].sum + a[a[k].r].sum + 1 : 0, k;
}
void pd(int k) {
a[a[k].l].w += a[k].tag, a[a[k].l].tag += a[k].tag;
a[a[k].r].w += a[k].tag, a[a[k].r].tag += a[k].tag;
a[k].tag = 0;
}
void split(int k, int v, int &x, int &y, int l = 0, int r = 0) {
if (!k) return;
pd(k), l = a[k].l, r = a[k].r;
((a[k].w <= v) ? (split(r, v, a[k].r = 0, y), x) : (split(l, v, x, a[k].l = 0), y)) = k;
update(k);
}
int merge(int x, int y) {
if (!x || !y) return x | y;
return update((a[x].v > a[y].v) ? (pd(x), a[x].r = merge(a[x].r, y), x) : (pd(y), a[y].l = merge(x, a[y].l), y));
}
void insert(int w, int x = 0, int y = 0) {
a[++tot] = {w, rand(), 0, 0, 1, 0};
split(root, w, x, y);
root = merge(merge(x, tot), y);
}
void G(int w) {
a[root].w += w, a[root].tag += w;
}
int At(int k, int x) {
if (!k) return -1;
pd(k);
if (a[a[k].r].sum + 1 < x) {
return At(a[k].l, x - a[a[k].r].sum - 1);
} else if (a[a[k].r].sum >= x) {
return At(a[k].r, x);
}
return a[k].w;
}
int upgrt(int k, int x) {
if (!k) return 0;
pd(k);
if (x <= a[k].w) {
return upgrt(a[k].l, x);
}
return upgrt(a[k].r, x) + a[a[k].l].sum + 1;
}
} tr;
int t, x, gz, ans;
char op;
int main() {
srand(time(NULL));
for (cin >> t >> gz; t; t--) {
cin >> op >> x;
if (op == 'I') {
if (x >= gz) {
tr.insert(x);
}
} else if (op == 'A') {
tr.G(x);
} else if (op == 'S') {
tr.G(-x);
int s = 0, b = 0;
tr.split(tr.root, gz - 1, s, b);
ans += tr.a[s].sum;
tr.root = b;
} else {
cout << tr.At(tr.root, x) << endl;
}
}
cout << ans << endl;
return 0;
}

暴力加减如何呢?

文艺平衡树

只记录了一个题目的,用法太少了,所以我选择补一个完全没必要的

#include <iostream>
#include <ctime>
using namespace std;
const int MaxN = 100010;
struct S {
int v, l, r, sum, tag;
} a[MaxN];
int root, tot, n, m;
int update(int k) {
return (k) && (a[k].sum = a[a[k].l].sum + a[a[k].r].sum + 1), k;
}
void pd(int k) {
if (!a[k].tag) return;
swap(a[k].l, a[k].r);
a[a[k].l].tag ^= 1;
a[a[k].r].tag ^= 1;
a[k].tag = 0;
}
int split(int k, int v, int &x, int &y, int l = 0, int r = 0) {
if (!k) return x = y = 0;
pd(k), l = a[k].l, r = a[k].r;
((a[l].sum + 1 <= v) ? (split(r, v - 1 - a[l].sum, a[k].r = 0, y), x) : (split(l, v, x, a[k].l = 0), y)) = k;
return update(k);
}
int merge(int x, int y) {
if (!x || !y) return x | y;
return update((a[x].v < a[y].v) ? (pd(x), a[x].r = merge(a[x].r, y), x) : (pd(y), a[y].l = merge(x, a[y].l), y));
}
void reverse(int l, int r) {
int tmp1 = 0, tmp2 = 0, tmp3 = 0;
split(root, r, tmp1, tmp3);
split(tmp1, l - 1, tmp1, tmp2);
a[tmp2].tag ^= 1;
root = merge(merge(tmp1, tmp2), tmp3);
}
void DFS(int x) {
if (!x) return;
pd(x);
DFS(a[x].l);
cout << x << " ";
DFS(a[x].r);
}
int main() {
srand(time(NULL));
cin >> n >> m;
for (int i = 1; i <= n; i++) {
a[i] = {rand(), 0, 0, 1, 0};
root = merge(root, i);
}
for (int i = 1, l, r; i <= m; i++) {
cin >> l >> r;
reverse(l, r);
}
DFS(root);
return 0;
}

本文作者:yabnto

本文链接:https://www.cnblogs.com/ybtarr/p/17639234.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   yabnto  阅读(19)  评论(0编辑  收藏  举报
  1. 1 イエスタデイ(翻自 Official髭男dism) 茶泡饭,春茶,kobasolo
  2. 2 光辉岁月 Audio artist
  3. 3 名前を呼ぶよ Audio artist
  4. 4 战歌 Audio artist
  5. 5 時を越えた想い Audio artist
  6. 6 所念皆星河 Audio artist
  7. 7 See you again Audio artist
See you again - Audio artist
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

Not available

点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起