数据结构
莫队
int n, m;
/*====================*/
int S;
struct Query
{
int l, r, idx;
Query(int _l = 0, int _r = 0, int _idx = 0)
{
l = _l, r = _r, idx = _idx;
}
friend bool operator<(const Query& a, const Query& b)
{
return (a.l / S == b.l / S) ? (((a.l / S) & 1) ? (a.r > b.r) : (a.r < b.r)) : (a.l < b.l);
}
}query[M];
/*====================*/
int ans[M];
/*====================*/
void Add(int pos)
{
}
void Del(int pos)
{
}
/*====================*/
void Solve(void)
{
cin >> n >> m;
S = n / sqrt(m) + 1;
for (int i = 1; i <= m; ++i)
{
int l, r; cin >> l >> r;
query[i] = Query(l, r, i);
}
sort(query + 1, query + 1 + m);
int l = 1, r = 0;
for (int i = 1; i <= m; ++i)
{
while (query[i].l < l)Add(--l);
while (r < query[i].r)Add(++r);
while (l < query[i].l)Del(l++);
while (query[i].r < r)Del(r--);
//获得ans[query[i].idx];
}
}
猫树
#include<iostream>
using namespace std;
const int N = 1 << 20;
const int LEVEL = 20;
int a[N];
int lg[N];
int pos[N];
int MaoA[LEVEL][N];//最大子段和
int MaoB[LEVEL][N];//最大连续和
inline int ls(int p) { return p << 1; }
inline int rs(int p) { return (p << 1) | 1; }
void Build(int p, int l, int r, int level)
{
if (l == r) { pos[l] = p; return; }
int mid = (l + r) >> 1;
int tempA, tempB;
//the left
MaoA[level][mid] = MaoB[level][mid] = a[mid];
tempA = max(a[mid], 0), tempB = a[mid];
for (int i = mid - 1; i >= l; --i)
{
tempA += a[i]; MaoA[level][i] = max(MaoA[level][i + 1], tempA); tempA = max(tempA, 0);
tempB += a[i]; MaoB[level][i] = max(MaoB[level][i + 1], tempB);
}
//the right
MaoA[level][mid + 1] = MaoB[level][mid + 1] = a[mid + 1];
tempA = max(a[mid + 1], 0), tempB = a[mid + 1];
for (int i = mid + 2; i <= r; ++i)
{
tempA += a[i]; MaoA[level][i] = max(MaoA[level][i - 1], tempA); tempA = max(tempA, 0);
tempB += a[i]; MaoB[level][i] = max(MaoB[level][i - 1], tempB);
}
//
Build(ls(p), l, mid, level + 1); Build(rs(p), mid + 1, r, level + 1);
}
int Ask(int l, int r)
{
if (l == r)return a[l];
int level = (lg[pos[l]] - lg[pos[l] ^ pos[r]]);
return max(max(MaoA[level][l], MaoA[level][r]), MaoB[level][l] + MaoB[level][r]);
}
int main()
{
int n; cin >> n;
int len = 1; while (len < n)len <<= 1;
for (int i = 2; i < N; ++i)lg[i] = lg[i >> 1] + 1;
for (int i = 1; i <= n; ++i)cin >> a[i];
Build(1, 1, len, 1);
int m; cin >> m;
for (int i = 1; i <= m; ++i)
{
int l, r; cin >> l >> r;
cout << Ask(l, r) << endl;
}
return 0;
}
ST表
template<class Type>
class C_ST
{
public:
Type operator()(int l, int r)
{
int d = __lg(r - l + 1); return op(table[d][l], table[d][r - (1 << d) + 1]);
}
void Init(int n, Type arr[], Type(*op)(Type, Type))
{
this->op = op;
/*====================*/
table.assign(__lg(n) + 1, vector<Type>(n + 1, Type()));
for (int i = 1; i <= n; ++i)table[0][i] = arr[i];
/*====================*/
for (int d = 1; (1 << d) <= n; ++d)
{
for (int i = 1; i + (1 << d) - 1 <= n; ++i)
{
table[d][i] = op(table[d - 1][i], table[d - 1][i + (1 << (d - 1))]);
}
}
}
private:
Type(*op)(Type, Type);
vector<vector<Type>>table;
};
扫描线
矩形面积并
namespace ScanLine
{
const int N = 1e5 + 10;
/*====================*/
struct Rectangle
{
double x1, y1;
double x2, y2;
};
Rectangle rectangle[N];
/*====================*/
vector<double>pos;
/*====================*/
struct Line
{
int val;
int l, r;
double h;
Line(int _l = 0, int _r = 0, double _h = 0, int _val = 0)
{
l = _l, r = _r, h = _h, val = _val;
}
friend bool operator<(const Line& a, const Line& b)
{
if (a.h != b.h)
{
return a.h < b.h;
}
else
{
return a.val > b.val;
}
}
};
vector<Line>line;
/*====================*/
struct Tree
{
int l, r;
int cnt; double len;
};
Tree tree[N << 3];
int ls(int p)
{
return p << 1;
}
int rs(int p)
{
return p << 1 | 1;
}
void PushUp(int p)
{
if (tree[p].cnt >= 1)
{
tree[p].len = pos[tree[p].r] - pos[tree[p].l - 1];
}
else
{
if (tree[p].l != tree[p].r)
{
tree[p].len = tree[ls(p)].len + tree[rs(p)].len;
}
else
{
tree[p].len = 0;
}
}
}
void Build(int p, int l, int r)
{
tree[p].l = l, tree[p].r = r;
tree[p].cnt = 0; tree[p].len = 0;
if (tree[p].l != tree[p].r)
{
int mid = (tree[p].l + tree[p].r) >> 1;
Build(ls(p), l, mid + 0);
Build(rs(p), mid + 1, r);
}
}
void Change(int p, int l, int r, int d)
{
if (l <= tree[p].l && tree[p].r <= r)
{
tree[p].cnt += d; PushUp(p);
}
else
{
int mid = (tree[p].l + tree[p].r) >> 1;
if (l <= mid)Change(ls(p), l, r, d);
if (mid < r) Change(rs(p), l, r, d);
PushUp(p);
}
}
/*====================*/
double Init(void)
{
int n; cin >> n;
pos.clear(); line.clear();
for (int i = 1; i <= n; ++i)
{
double x1, y1; cin >> x1 >> y1;//左上
double x2, y2; cin >> x2 >> y2;//右下
pos.push_back(x1); pos.push_back(x2);
rectangle[i].x1 = x1; rectangle[i].y1 = y1;
rectangle[i].x2 = x2; rectangle[i].y2 = y2;
}
sort(pos.begin(), pos.end());
pos.erase(unique(pos.begin(), pos.end()), pos.end());
for (int i = 1; i <= n; ++i)
{
int l = lower_bound(pos.begin(), pos.end(), rectangle[i].x1) - pos.begin();
int r = lower_bound(pos.begin(), pos.end(), rectangle[i].x2) - pos.begin();
line.push_back(Line(l, r, rectangle[i].y1, +1));
line.push_back(Line(l, r, rectangle[i].y2, -1));
}
sort(line.begin(), line.end());
Build(1, 1, pos.size() - 1);
bool flag = true;
double ans = 0.0;
double last = 0.0;
auto it = line.begin();
while (it != line.end())
{
double high = it->h;
if (flag)last = high, flag = false;
ans += (high - last) * tree[1].len;
while (it != line.end() && it->h == high)
{
Change(1, it->l + 1, it->r, it->val); it++;
}
last = high;
}
return ans;
}
}
矩形面积交
namespace ScanLine
{
const int N = 1e5 + 10;
/*====================*/
struct Rectangle
{
double x1, y1;
double x2, y2;
};
Rectangle rectangle[N];
/*====================*/
vector<double>pos;
/*====================*/
struct Line
{
int val;
int l, r;
double h;
Line(int _l = 0, int _r = 0, double _h = 0, int _val = 0)
{
l = _l, r = _r, h = _h, val = _val;
}
friend bool operator<(const Line& a, const Line& b)
{
if (a.h != b.h)
{
return a.h < b.h;
}
else
{
return a.val > b.val;
}
}
};
vector<Line>line;
/*====================*/
struct Tree
{
int cnt;
int l, r;
double len1;
double len2;
};
Tree tree[N << 3];
int ls(int p)
{
return p << 1;
}
int rs(int p)
{
return p << 1 | 1;
}
void PushUp(int p)
{
if (tree[p].cnt >= 1)
{
tree[p].len1 = pos[tree[p].r] - pos[tree[p].l - 1];
}
else
{
if (tree[p].l != tree[p].r)
{
tree[p].len1 = tree[ls(p)].len1 + tree[rs(p)].len1;
}
else
{
tree[p].len1 = 0;
}
}
if (tree[p].cnt >= 2)
{
tree[p].len2 = pos[tree[p].r] - pos[tree[p].l - 1];
}
else
{
if (tree[p].l != tree[p].r)
{
if (tree[p].cnt == 1)
{
tree[p].len2 = tree[ls(p)].len1 + tree[rs(p)].len1;
}
else
{
tree[p].len2 = tree[ls(p)].len2 + tree[rs(p)].len2;
}
}
else
{
tree[p].len2 = 0;
}
}
}
void Build(int p, int l, int r)
{
tree[p].cnt = 0;
tree[p].l = l, tree[p].r = r;
tree[p].len1 = 0; tree[p].len2 = 0;
if (tree[p].l != tree[p].r)
{
int mid = (tree[p].l + tree[p].r) >> 1;
Build(ls(p), l, mid + 0);
Build(rs(p), mid + 1, r);
}
}
void Change(int p, int l, int r, int d)
{
if (l <= tree[p].l && tree[p].r <= r)
{
tree[p].cnt += d; PushUp(p);
}
else
{
int mid = (tree[p].l + tree[p].r) >> 1;
if (l <= mid)Change(ls(p), l, r, d);
if (mid < r) Change(rs(p), l, r, d);
PushUp(p);
}
}
/*====================*/
double Init(void)
{
int n; cin >> n;
pos.clear(); line.clear();
for (int i = 1; i <= n; ++i)
{
double x1, y1; cin >> x1 >> y1;//左上
double x2, y2; cin >> x2 >> y2;//右下
pos.push_back(x1); pos.push_back(x2);
rectangle[i].x1 = x1; rectangle[i].y1 = y1;
rectangle[i].x2 = x2; rectangle[i].y2 = y2;
}
sort(pos.begin(), pos.end());
pos.erase(unique(pos.begin(), pos.end()), pos.end());
for (int i = 1; i <= n; ++i)
{
int l = lower_bound(pos.begin(), pos.end(), rectangle[i].x1) - pos.begin();
int r = lower_bound(pos.begin(), pos.end(), rectangle[i].x2) - pos.begin();
line.push_back(Line(l, r, rectangle[i].y1, +1));
line.push_back(Line(l, r, rectangle[i].y2, -1));
}
sort(line.begin(), line.end());
Build(1, 1, pos.size() - 1);
bool flag = true;
double ans = 0.0;
double last = 0.0;
auto it = line.begin();
while (it != line.end())
{
double high = it->h;
if (flag)last = high, flag = false;
ans += (high - last) * tree[1].len2;
while (it != line.end() && it->h == high)
{
Change(1, it->l + 1, it->r, it->val); it++;
}
last = high;
}
return ans;
}
}
矩形周长并
namespace ScanLine
{
const int N = 1e5 + 10;
/*====================*/
struct Rectangle
{
double x1, y1;
double x2, y2;
};
Rectangle rectangle[N];
/*====================*/
vector<double>pos;
/*====================*/
struct Line
{
int val;
int l, r;
double h;
Line(int _l = 0, int _r = 0, double _h = 0, int _val = 0)
{
l = _l, r = _r, h = _h, val = _val;
}
friend bool operator<(const Line& a, const Line& b)
{
if (a.h != b.h)
{
return a.h < b.h;
}
else
{
return a.val > b.val;
}
}
};
vector<Line>line;
typedef vector<Line>::iterator iter;
/*====================*/
struct Tree
{
int l, r;
int cnt; double len;
};
Tree tree[N << 3];
int ls(int p)
{
return p << 1;
}
int rs(int p)
{
return p << 1 | 1;
}
void PushUp(int p)
{
if (tree[p].cnt >= 1)
{
tree[p].len = pos[tree[p].r] - pos[tree[p].l - 1];
}
else
{
if (tree[p].l != tree[p].r)
{
tree[p].len = tree[ls(p)].len + tree[rs(p)].len;
}
else
{
tree[p].len = 0;
}
}
}
void Build(int p, int l, int r)
{
tree[p].l = l, tree[p].r = r;
tree[p].cnt = 0; tree[p].len = 0;
if (tree[p].l != tree[p].r)
{
int mid = (tree[p].l + tree[p].r) >> 1;
Build(ls(p), l, mid + 0);
Build(rs(p), mid + 1, r);
}
}
void Change(int p, int l, int r, int d)
{
if (l <= tree[p].l && tree[p].r <= r)
{
tree[p].cnt += d; PushUp(p);
}
else
{
int mid = (tree[p].l + tree[p].r) >> 1;
if (l <= mid)Change(ls(p), l, r, d);
if (mid < r) Change(rs(p), l, r, d);
PushUp(p);
}
}
/*====================*/
double Init(void)
{
int n; cin >> n; double ans = 0;
for (int i = 1; i <= n; ++i)
{
double x1, y1; cin >> x1 >> y1;//左上
double x2, y2; cin >> x2 >> y2;//右下
rectangle[i].x1 = x1; rectangle[i].y1 = y1;
rectangle[i].x2 = x2; rectangle[i].y2 = y2;
}
/*====================*/
pos.clear(); line.clear();
for (int i = 1; i <= n; ++i)
{
pos.push_back(rectangle[i].x1);
pos.push_back(rectangle[i].x2);
}
sort(pos.begin(), pos.end());
pos.erase(unique(pos.begin(), pos.end()), pos.end());
for (int i = 1; i <= n; ++i)
{
int l = lower_bound(pos.begin(), pos.end(), rectangle[i].x1) - pos.begin();
int r = lower_bound(pos.begin(), pos.end(), rectangle[i].x2) - pos.begin();
line.push_back(Line(l, r, rectangle[i].y1, +1));
line.push_back(Line(l, r, rectangle[i].y2, -1));
}
sort(line.begin(), line.end());
Build(1, 1, pos.size() - 1);
double last1 = 0;
for (iter it = line.begin(); it != line.end(); ++it)
{
Change(1, it->l + 1, it->r, it->val);
ans += abs(tree[1].len - last1); last1 = tree[1].len;
}
/*====================*/
pos.clear(); line.clear();
for (int i = 1; i <= n; ++i)
{
pos.push_back(rectangle[i].y1);
pos.push_back(rectangle[i].y2);
}
sort(pos.begin(), pos.end());
pos.erase(unique(pos.begin(), pos.end()), pos.end());
for (int i = 1; i <= n; ++i)
{
int l = lower_bound(pos.begin(), pos.end(), rectangle[i].y1) - pos.begin();
int r = lower_bound(pos.begin(), pos.end(), rectangle[i].y2) - pos.begin();
line.push_back(Line(l, r, rectangle[i].x1, +1));
line.push_back(Line(l, r, rectangle[i].x2, -1));
}
sort(line.begin(), line.end());
Build(1, 1, pos.size() - 1);
double last2 = 0;
for (iter it = line.begin(); it != line.end(); ++it)
{
Change(1, it->l + 1, it->r, it->val);
ans += abs(tree[1].len - last2); last2 = tree[1].len;
}
/*====================*/
return ans;
}
}
可删堆
template<class Type, class Comp = greater<Type>>
class C_Heap
{
private:
priority_queue<Type, vector<Type>, Comp>heap1;
priority_queue<Type, vector<Type>, Comp>heap2;
public:
Type Top(void)
{
while (!heap2.Empty() && heap1.Top() == heap2.Top())
{
heap1.Pop(); heap2.Pop();
}
return heap1.Top();
}
void Pop(void)
{
while (!heap2.Empty() && heap1.Top() == heap2.Top())
{
heap1.Pop(); heap2.Pop();
}
heap1.Pop();
}
int Size(void)
{
return heap1.Size() - heap2.Size();
}
void Clear(void)
{
while (!heap1.Empty())heap1.Pop();
while (!heap2.Empty())heap2.Pop();
}
bool Empty(void)
{
return heap1.Size() == heap2.Size();
}
void Erase(Type val)
{
heap2.push(val);
}
void Insert(Type val)
{
heap1.push(val);
}
};
并查集
class C_DSU
{
private:
vector<int>pre, siz;
/*====================*/
int Find(int cur)
{
return cur == pre[cur] ? cur : pre[cur] = Find(pre[cur]);
}
public:
void Init(int n)
{
pre.assign(n + 1, 0);siz.assign(n + 1, 1);
for (int i = 0; i <= n; ++i)pre[i] = i;
}
int operator[](int cur)
{
return Find(cur);
}
void operator()(int u, int v)
{
u = Find(u), v = Find(v);
if (siz[u] < siz[v])
{
pre[u] = v, siz[v] += siz[u];
}
else
{
pre[v] = u, siz[u] += siz[v];
}
}
};
主席树
template<class Valu>
class C_ChairmanTree
{
private:
struct Tree
{
int cnt;
int ls, rs;
Tree(void)
{
cnt = 0;
ls = rs = -1;
}
};
/*====================*/
vector<int>root;
vector<Tree>tree;
/*====================*/
int Creat(void)
{
tree.push_back(Tree());
return tree.size() - 1;
}
void Build(int& cur, int treel, int treer)
{
cur = Creat();
if (treel == treer)return;
int mid = (treel + treer) >> 1;
Build(tree[cur].ls, treel, mid + 0);
Build(tree[cur].rs, mid + 1, treer);
}
void Insert(int pre, int& cur, int x, int treel, int treer)
{
cur = Creat();
tree[cur] = tree[pre]; tree[cur].cnt++;
if (treel == treer)return;
int mid = (treel + treer) >> 1;
if (x <= mid)Insert(tree[pre].ls, tree[cur].ls, x, treel, mid + 0);
if (mid < x) Insert(tree[pre].rs, tree[cur].rs, x, mid + 1, treer);
}
int Ask(int pre, int cur, int k, int treel, int treer)
{
if (treel == treer)return treel;
int mid = (treel + treer) >> 1;
int cnt = tree[tree[cur].ls].cnt - tree[tree[pre].ls].cnt;
if (cnt < k)return Ask(tree[pre].rs, tree[cur].rs, k - cnt, mid + 1, treer);
else return Ask(tree[pre].ls, tree[cur].ls, k, treel, mid + 0);
}
/*====================*/
vector<Valu>lib;
public:
void Init(int n, Valu arr[])
{
for (int i = 1; i <= n; ++i)
{
lib.push_back(arr[i]);
}
sort(lib.begin(), lib.end());
lib.erase(unique(lib.begin(), lib.end()), lib.end());
/*====================*/
tree.reserve(2 * lib.size() + n * (ceil(log2(lib.size())) + 1));
/*====================*/
root.assign(n + 1, -1);
Build(root[0], 1, lib.size());
for (int i = 1; i <= n; ++i)
{
int x = lower_bound(lib.begin(), lib.end(), arr[i]) - lib.begin() + 1;
Insert(root[i - 1], root[i], x, 1, lib.size());
}
}
Valu operator()(int l, int r, int k)
{
return lib[Ask(root[l - 1], root[r], k, 1, lib.size()) - 1];
}
};
平衡树
带旋·Treap·权值树
template<class Valu>
class C_Treap
{
private:
struct Tree
{
int siz;
Valu valu;
int priority;
Tree* lch, * rch;
Tree(void)
{
siz = 0;
valu = Valu();
lch = rch = NULL;
priority = rand();
}
};
/*====================*/
Tree* null, * root;
/*====================*/
Tree* Creat(Valu valu)
{
Tree* node = new Tree;
node->valu = valu;
node->lch = null;
node->rch = null;
node->siz = 1;
return node;
}
/*====================*/
void PushUp(Tree* cur)
{
cur->siz = cur->lch->siz + cur->rch->siz + 1;
}
/*====================*/
void LRotate(Tree*& cur)
{
Tree* son = cur->rch;
cur->rch = son->lch; son->lch = cur; cur = son;
PushUp(cur->lch); PushUp(cur);
}
void RRotate(Tree*& cur)
{
Tree* son = cur->lch;
cur->lch = son->rch; son->rch = cur; cur = son;
PushUp(cur->rch); PushUp(cur);
}
/*====================*/
void Insert(Tree*& cur, Valu valu)
{
if (cur == null)
{
cur = Creat(valu);
}
else
{
if (valu < cur->valu)
{
Insert(cur->lch, valu);
if (cur->priority < cur->lch->priority)
{
RRotate(cur);
}
}
else
{
Insert(cur->rch, valu);
if (cur->priority < cur->rch->priority)
{
LRotate(cur);
}
}
PushUp(cur);
}
}
void Delete(Tree*& cur, Valu valu)
{
if (cur == null)return;
if (valu == cur->valu)
{
if (cur->lch != null && cur->rch != null)
{
if (cur->lch->priority < cur->rch->priority)
{
LRotate(cur); Delete(cur->lch, valu); PushUp(cur);
}
else
{
RRotate(cur); Delete(cur->rch, valu); PushUp(cur);
}
}
else if (cur->lch != null)
{
RRotate(cur); Delete(cur->rch, valu); PushUp(cur);
}
else if (cur->rch != null)
{
LRotate(cur); Delete(cur->lch, valu); PushUp(cur);
}
else
{
delete cur; cur = null;
}
}
else
{
if (valu < cur->valu)
{
Delete(cur->lch, valu);
}
else
{
Delete(cur->rch, valu);
}
PushUp(cur);
}
}
/*====================*/
Valu GetValuByRank(int rank)
{
Tree* cur = root;
while (cur != null)
{
if (cur->lch->siz + 1 == rank)
{
return cur->valu;
}
else
{
if (cur->lch->siz < rank)
{
rank -= cur->lch->siz + 1;
cur = cur->rch;
}
else
{
cur = cur->lch;
}
}
}
return Valu();
}
int GetRankByValu(Valu valu)
{
int res = 1;
Tree* cur = root;
while (cur != null)
{
if (cur->valu < valu)
{
res += cur->lch->siz + 1;
cur = cur->rch;
}
else
{
cur = cur->lch;
}
}
return res;
}
/*====================*/
void Clear(Tree* cur)
{
if (cur != null)
{
Clear(cur->lch);
Clear(cur->rch);
delete cur;
}
}
public:
C_Treap(void)
{
root = null = new Tree;
}
~C_Treap(void)
{
Clear(root); delete null;
}
/*====================*/
int Size(void)
{
return root->siz;
}
void Clear(void)
{
Clear(root); root = null;
}
bool Empty(void)
{
return root->siz == 0;
}
void Erase(Valu valu)
{
Delete(root, valu);
}
void Insert(Valu valu)
{
Insert(root, valu);
}
int operator()(Valu valu)
{
return GetRankByValu(valu);
}
Valu operator[](int rank)
{
return GetValuByRank(rank);
}
};
无旋·Treap·序列树
template<class Valu>
class C_Treap
{
public:
struct Tree
{
int siz = 0;
Valu valu = Valu();
int priority = rand();
Tree* lch = NULL, * rch = NULL;
};
/*====================*/
Tree* null, * root;
/*====================*/
Tree* Creat(Valu valu)
{
Tree* node = new Tree;
node->valu = valu;
node->lch = null;
node->rch = null;
node->siz = 1;
return node;
}
/*====================*/
void PushUp(Tree* cur)
{
cur->siz = cur->lch->siz + cur->rch->siz + 1;
}
void PushDown(Tree* cur)
{
/*
* 预留
*/
}
/*====================*/
Tree* Build(int l, int r, Valu arr[])
{
if (l > r)return null;
int mid = (l + r) >> 1;
Tree* cur = Creat(arr[mid]);
cur->lch = Build(l, mid - 1, arr);
cur->rch = Build(mid + 1, r, arr);
PushUp(cur); return cur;
}
Tree* Build(int l, int r, vector<Valu>& arr)
{
if (l > r)return null;
int mid = (l + r) >> 1;
Tree* cur = Creat(arr[mid]);
cur->lch = Build(l, mid - 1, arr);
cur->rch = Build(mid + 1, r, arr);
PushUp(cur); return cur;
}
/*====================*/
void Lower_Split(Tree* cur, int index, Tree*& ltree, Tree*& rtree)//index留在rtree
{
if (cur == null)
{
ltree = rtree = null; return;
}
PushDown(cur);
if (cur->lch->siz + 1 < index)
{
Lower_Split(cur->rch, index - cur->lch->siz - 1, ltree, rtree);
cur->rch = ltree; PushUp(cur); ltree = cur;
}
else
{
Lower_Split(cur->lch, index, ltree, rtree);
cur->lch = rtree; PushUp(cur); rtree = cur;
}
}
void Upper_Split(Tree* cur, int index, Tree*& ltree, Tree*& rtree)//index留在ltree
{
if (cur == null)
{
ltree = rtree = null; return;
}
PushDown(cur);
if (cur->lch->siz < index)
{
Upper_Split(cur->rch, index - cur->lch->siz - 1, ltree, rtree);
cur->rch = ltree; PushUp(cur); ltree = cur;
}
else
{
Upper_Split(cur->lch, index, ltree, rtree);
cur->lch = rtree; PushUp(cur); rtree = cur;
}
}
/*====================*/
Tree* Merge(Tree* ltree, Tree* rtree)
{
if (ltree == null)return rtree;
if (rtree == null)return ltree;
PushDown(ltree); PushDown(rtree);
if (ltree->priority < rtree->priority)
{
rtree->lch = Merge(ltree, rtree->lch);
PushUp(rtree); return rtree;
}
else
{
ltree->rch = Merge(ltree->rch, rtree);
PushUp(ltree); return ltree;
}
}
/*====================*/
void Split(int l, int r, Tree*& ltree, Tree*& mtree, Tree*& rtree)
{
Tree* o1, * o2, * o3, * o4;
Upper_Split(root, r, o1, o2);
Lower_Split(o1, l, o3, o4);
ltree = o3, mtree = o4, rtree = o2;
}
void Merge(Tree* ltree, Tree* mtree, Tree* rtree)
{
root = Merge(Merge(ltree, mtree), rtree);
}
/*====================*/
Valu operator[](int rank)
{
Tree* cur = root;
while (cur != null)
{
PushDown(cur);
if (cur->lch->siz + 1 == rank)
{
return cur->valu;
}
else
{
if (cur->lch->siz < rank)
{
rank -= cur->lch->siz + 1;
cur = cur->rch;
}
else
{
cur = cur->lch;
}
}
}
return Valu();
}
/*====================*/
C_Treap(void)
{
root = null = new Tree;
}
void Clear(Tree* cur)
{
if (cur != null)
{
Clear(cur->lch);
Clear(cur->rch);
delete cur;
}
}
~C_Treap(void)
{
Clear(root); delete null;
}
};
双旋·Splay·权值树
template<class Type>
class Splay
{
public:
~Splay(void)
{
Clear(root);
delete null;
}
int size(void)
{
return count;
}
void clear(void)
{
Clear(root);
root = null;
}
bool empty(void)
{
return count == 0;
}
Type pre(Type val)
{
root = splay(FindPre(root, val));
return root->val;
}
Type nxt(Type val)
{
root = splay(FindNxt(root, val));
return root->val;
}
void erase(Type val)
{
count--; root = Delete(FindByValu(root, val));
}
void insert(Type val)
{
count++; root = splay(Insert(root, val));
}
int operator()(Type val)
{
root = splay(FindByValu(root, val));
return root->lch->siz + 1;
}
Type operator[](int rank)
{
root = splay(FindByRank(root, rank));
return root->val;
}
Type lower_bound(Type val)
{
root = splay(FindLower(root, val));
return root->val;
}
Type upper_bound(Type val)
{
root = splay(FindUpper(root, val));
return root->val;
}
private:
struct Node
{
int siz = 0;
Type val = Type();
Node* fa = NULL;
Node* lch = NULL;
Node* rch = NULL;
};
/*====================*/
typedef bool CHILD;
const CHILD LCH = true;
const CHILD RCH = false;
/*====================*/
int count = 0;
Node* null = new Node;
Node* root = null;
/*====================*/
CHILD Child(Node* cur)
{
Node* pre = cur->fa;
if (pre->lch == cur)
{
return LCH;
}
else
{
return RCH;
}
}
void PushUp(Node* cur)
{
cur->siz = cur->lch->siz + cur->rch->siz + 1;
}
void Del(Node* cur, Node* pre, CHILD WCH)
{
cur->fa = null;
if (WCH == LCH)pre->lch = null;
if (WCH == RCH)pre->rch = null;
}
void Add(Node* cur, Node* pre, CHILD WCH)
{
cur->fa = pre;
if (WCH == LCH)pre->lch = cur;
if (WCH == RCH)pre->rch = cur;
}
void LRotate(Node* cur)
{
Node* pre = cur->fa, * nxt = cur->lch, * anc = pre->fa;
CHILD WCH = Child(pre);
Del(nxt, cur, LCH); Del(cur, pre, RCH); Del(pre, anc, WCH);
Add(nxt, pre, RCH); Add(pre, cur, LCH); Add(cur, anc, WCH);
PushUp(pre); PushUp(cur);
}
void RRotate(Node* cur)
{
Node* pre = cur->fa, * nxt = cur->rch, * anc = pre->fa;
CHILD WCH = Child(pre);
Del(nxt, cur, RCH); Del(cur, pre, LCH); Del(pre, anc, WCH);
Add(nxt, pre, LCH); Add(pre, cur, RCH); Add(cur, anc, WCH);
PushUp(pre); PushUp(cur);
}
void Rotate(Node* cur)
{
if (Child(cur) == LCH)
{
RRotate(cur);
}
else
{
LRotate(cur);
}
}
void Clear(Node* cur)
{
if (cur != null)
{
Clear(cur->lch);
Clear(cur->rch);
delete cur;
}
}
Node* Creat(Type val)
{
Node* cur = new Node;
cur->lch = null;
cur->rch = null;
cur->fa = null;
cur->val = val;
cur->siz = 1;
return cur;
}
Node* splay(Node* cur)
{
while (true)
{
Node* pre = cur->fa;
if (cur->fa == null)break;
if (pre->fa == null)break;
CHILD CHpre = Child(pre);
CHILD CHcur = Child(cur);
if (CHpre == CHcur)
{
Rotate(pre); Rotate(cur); continue;
}
if (CHpre != CHcur)
{
Rotate(cur); Rotate(cur); continue;
}
}
if (cur->fa != null)Rotate(cur); return cur;
}
Node* Insert(Node* cur, Type val)
{
CHILD WCH = LCH; Node* pre = null;
while (cur != null)
{
if (val < cur->val)
{
pre = cur; cur = cur->lch; WCH = LCH;
}
else
{
pre = cur; cur = cur->rch; WCH = RCH;
}
}
cur = Creat(val); Add(cur, pre, WCH); return cur;
}
Node* Delete(Node* cur)
{
splay(cur);
Node* lch = cur->lch;
Node* rch = cur->rch;
delete cur; return Merge(lch, rch);
}
Node* Merge(Node* ltree, Node* rtree)
{
if (ltree == null)
{
rtree->fa = null; return rtree;
}
if (rtree == null)
{
ltree->fa = null; return ltree;
}
ltree->fa = null; rtree->fa = null;
if (ltree->siz < rtree->siz)
{
Node* cur = FindMax(ltree); splay(cur);
Add(rtree, cur, RCH); PushUp(cur); return cur;
}
else
{
Node* cur = FindMin(rtree); splay(cur);
Add(ltree, cur, LCH); PushUp(cur); return cur;
}
}
Node* FindByValu(Node* cur, Type val)
{
Node* res = null;
while (cur != null)
{
if (val == cur->val)
{
res = cur, cur = cur->lch;
}
else
{
if (val < cur->val)
{
cur = cur->lch;
}
else
{
cur = cur->rch;
}
}
}
return res;
}
Node* FindByRank(Node* cur, int rank)
{
while (cur != null)
{
if (cur->lch->siz + 1 == rank)
{
return cur;
}
else
{
if (cur->lch->siz < rank)
{
rank -= cur->lch->siz + 1;
cur = cur->rch;
}
else
{
cur = cur->lch;
}
}
}
return null;
}
Node* FindLower(Node* cur, Type val)
{
Node* res = null;
while (cur != null)
{
if (cur->val < val)
{
cur = cur->rch;
}
else
{
res = cur;
cur = cur->lch;
}
}
return res;
}
Node* FindUpper(Node* cur, Type val)
{
Node* res = null;
while (cur != null)
{
if (val < cur->val)
{
res = cur;
cur = cur->lch;
}
else
{
cur = cur->rch;
}
}
return res;
}
Node* FindMin(Node* cur)
{
while (cur->lch != null)
{
cur = cur->lch;
}
return cur;
}
Node* FindMax(Node* cur)
{
while (cur->rch != null)
{
cur = cur->rch;
}
return cur;
}
Node* FindPre(Node* cur, Type val)
{
Node* res = null;
while (cur != null)
{
if (cur->val < val)
{
res = cur;
cur = cur->rch;
}
else
{
cur = cur->lch;
}
}
return res;
}
Node* FindNxt(Node* cur, Type val)
{
Node* res = null;
while (cur != null)
{
if (val < cur->val)
{
res = cur;
cur = cur->lch;
}
else
{
cur = cur->rch;
}
}
return res;
}
};
珂朵莉树
namespace Chtholly
{
struct Tree
{
int l, r;
mutable int val;
Tree(int _l = 0, int _r = 0, int _val = int())
{
l = _l, r = _r, val = _val;
}
friend bool operator<(const Tree& a, const Tree& b)
{
return a.l < b.l;
}
int len(void)const { return r - l + 1; }
};
/*====================*/
int n; set<Tree>tree;
/*====================*/
set<Tree>::iterator Find(int pos)
{
return --tree.upper_bound(Tree(pos));
}
set<Tree>::iterator Split(int pos)//lower
{
if (pos > n)return tree.end();
auto it = Find(pos); if (it->l == pos)return it;
int l = it->l, r = it->r; auto val = it->val; tree.erase(it);
tree.insert(Tree(l, pos - 1, val)); return tree.insert(Tree(pos, r, val)).first;
}
/*====================*/
void GetRange(int l, int r, auto& begin, auto& end)
{
end = Split(r + 1), begin = Split(l);
}
void EraseRange(int l, int r)
{
set<Tree>::iterator begin, end; GetRange(l, r, begin, end); tree.erase(begin, end);
}
void InsertRange(int l, int r, int val)
{
EraseRange(l, r); auto it = tree.insert(Tree(l, r, val)).first;
{auto __it = it; __it--; if (it != tree.begin() && __it->val == val)l = __it->l; }
{auto __it = it; __it++; if (__it != tree.end() && __it->val == val)r = __it->r; }
EraseRange(l, r); tree.insert(Tree(l, r, val));
}
/*====================*/
void Build(int _n)
{
n = _n; tree.insert(Tree(1, n, 1));
}
}
树状数组
权值树状数组
class C_FenwickTree
{
private:
int n, m; vector<int>tree;
/*====================*/
int lowbit(int x) { return x & (-x); }
public:
int Size(void)
{
return tree[0];
}
void Init(int n)
{
this->n = n; m = 0;
tree.assign(n + 1, 0);
while ((1 << (m + 1)) <= n)m++;
}
bool Empty(void)
{
return tree[0] == 0;
}
void Erase(int x)
{
tree[0]--;
while (x <= n)
{
tree[x] -= 1; x += lowbit(x);
}
}
void Insert(int x)
{
tree[0]++;
while (x <= n)
{
tree[x] += 1; x += lowbit(x);
}
}
int operator()(int valu)
{
valu--;
int rank = 0;
while (valu)
{
rank += tree[valu];
valu -= lowbit(valu);
}
return rank + 1;
}
int operator[](int rank)
{
int sum = 0, valu = 0;
for (int i = m; i >= 0; --i)
{
int temp = valu + (1 << i);
if (temp <= n && sum + tree[temp] < rank)
{
sum += tree[temp]; valu = temp;
}
}
return valu + 1;
}
};
一维树状数组
template<class Type>
class FenwickTree
{
public:
Type ask(int pos)
{
Type res = Type();
while (pos)
{
res += tree[pos];
pos -= lowbit(pos);
}
return res;
}
void init(int n)
{
this->n = n;
tree = new Type[n + 1];
for (int i = 0; i <= n; ++i)
{
tree[i] = Type();
}
}
~FenwickTree(void)
{
delete[] tree;
}
void add(int pos, Type d)
{
while (pos <= n)
{
tree[pos] += d;
pos += lowbit(pos);
}
}
Type ask(int l, int r)
{
Type res = Type(); l--;
while (r > l)res += tree[r], r -= lowbit(r);
while (l > r)res -= tree[l], l -= lowbit(l);
return res;
}
private:
int n = 0;
Type* tree = NULL;
/*====================*/
int lowbit(int x) { return x & (-x); }
};
二维树状数组
template<class Type>
class FenwickTree
{
public:
~FenwickTree(void)
{
for (int i = 0; i <= n; ++i)
{
delete[] tree[i];
}
delete[] tree;
}
Type ask(int x, int y)
{
Type res = Type();
while (x)
{
int tempy = y;
while (tempy)
{
res += tree[x][tempy];
tempy -= lowbit(tempy);
}
x -= lowbit(x);
}
return res;
}
void init(int n, int m)
{
this->n = n;
this->m = m;
tree = new Type * [n + 1];
for (int i = 0; i <= n; ++i)
{
tree[i] = new Type[m + 1];
for (int j = 0; j <= m; ++j)
{
tree[i][j] = Type();
}
}
}
void add(int x, int y, Type d)
{
while (x <= n)
{
int tempy = y;
while (tempy <= m)
{
tree[x][tempy] += d;
tempy += lowbit(tempy);
}
x += lowbit(x);
}
}
Type ask(int x1, int y1, int x2, int y2)
{
return ask(x2, y2) - ask(x1 - 1, y2) - ask(x2, y1 - 1) + ask(x1 - 1, y1 - 1);
}
private:
int n = 0, m = 0;
Type** tree = NULL;
/*====================*/
int lowbit(int x) { return x & (-x); }
};
区间mex
class Range_MEX
{
public:
Range_MEX(int n, int arr[], int l, int r)
{
root = new int[n + 1];
tree = new Tree[4200000 + 10];
for (int i = 0; i <= n; ++i)root[i] = -1;
BuildZero(root[0], l, r);
for (int i = 1; i <= n; ++i)
{
BuildChain(root[i - 1], root[i], i, arr[i]);
}
}
int operator()(int l, int r)
{
return Ask(root[r], l);
}
~Range_MEX(void)
{
delete[] tree;
delete[] root;
}
private:
struct Tree
{
int idx;
int l, r;
int ls, rs;
Tree(void)
{
idx = 0;
l = 0, r = 0;
ls = -1, rs = -1;
}
};
/*====================*/
int * root;
Tree* tree; int cnt = -1;
/*====================*/
void PushUp(int cur)
{
tree[cur].idx = min(tree[tree[cur].ls].idx, tree[tree[cur].rs].idx);
}
/*====================*/
void BuildZero(int& cur, int l, int r)
{
if (cur == -1)cur = ++cnt;
/*====================*/
tree[cur].l = l, tree[cur].r = r;
if (l != r)
{
int mid = (l + r) >> 1;
BuildZero(tree[cur].ls, l, mid + 0);
BuildZero(tree[cur].rs, mid + 1, r);
}
}
void BuildChain(int& pre, int& cur, int idx, int val)
{
if (cur == -1)cur = ++cnt;
/*====================*/
tree[cur].l = tree[pre].l, tree[cur].r = tree[pre].r;
tree[cur].ls = tree[pre].ls, tree[cur].rs = tree[pre].rs;
if (tree[cur].l == tree[cur].r)
{
tree[cur].idx = idx;
}
else
{
int mid = (tree[cur].l + tree[cur].r) >> 1;
if (val <= mid)BuildChain(tree[pre].ls, tree[cur].ls = -1, idx, val);
if (mid < val) BuildChain(tree[pre].rs, tree[cur].rs = -1, idx, val);
PushUp(cur);
}
}
/*====================*/
int Ask(int& cur, int l)
{
if (tree[cur].l == tree[cur].r)return tree[cur].l;
if (tree[tree[cur].ls].idx < l)return Ask(tree[cur].ls, l);
if (tree[tree[cur].rs].idx < l)return Ask(tree[cur].rs, l);
return tree[cur].r + 1;
}
};
Hash_MAP
const int Base = 19260817;
class Hash_Map
{
public:
Hash_Map()
{
memset(head, -1, sizeof(head));
nxt.reserve(1e7);
key.reserve(1e7);
val.reserve(1e7);
}
lnt& operator[](lnt k)
{
int h = hash(k);
for (int i = head[h]; ~i; i = nxt[i])
{
if (key[i] == k)
{
return val[i];
}
}
nxt.push_back(head[h]);
key.push_back(k);
val.push_back(0);
head[h] = nxt.size() - 1;
return val.back();
}
lnt has_key(lnt k)
{
int h = hash(k);
for (int i = head[h]; ~i; i = nxt[i])
{
if (key[i] == k)
{
return true;
}
}
return false;
}
private:
int head[Base];
vector<int>nxt;
vector<lnt>key;
vector<lnt>val;
int hash(lnt k)
{
return k % Base;
}
};
线段树合并
/*
* 与动态开点权值线段树搭配使用
*/
Tree* Merge(Tree*& a, Tree*& b, int treel, int treer)
{
Tree* cur = null;
if (a == null)
{
cur = b; b = null; return cur;
}
if (b == null)
{
cur = a; a = null; return cur;
}
cur = Creat();
if (treel == treer)
{
cur->siz = a->siz + b->siz;
}
else
{
int mid = (treel + treer) >> 1;
cur->ls = Merge(a->ls, b->ls, treel, mid + 0);
cur->rs = Merge(a->rs, b->rs, mid + 1, treer);
cur->siz = cur->ls->siz + cur->rs->siz;
}
delete a; a = null; delete b; b = null; return cur;
}
李超线段树
class C_LiChaoTree
{
private:
struct Function
{
int k, b;
int operator()(int x)
{
return k * x + b;
}
Function(int _k = 0, int _b = +INF)
{
k = _k, b = _b;
}
};
/*====================*/
struct Tree
{
Function f;
Tree* ls, * rs;
Tree(void)
{
ls = rs = NULL;
}
};
/*====================*/
Tree* root; int treel, treer;
/*====================*/
void PushDown(Tree*& cur, Function f, int treel, int treer)
{
if (cur == NULL)cur = new Tree;
int mid = (treel + treer) >> 1;
if (treel != treer)
{
if (cur->f.k < f.k)
{
if (f(mid) < cur->f(mid))
{
PushDown(cur->rs, cur->f, treel, mid + 0);
}
else
{
PushDown(cur->ls, f, mid + 1, treer);
}
}
else
{
if (f(mid) < cur->f(mid))
{
PushDown(cur->ls, cur->f, treel, mid + 0);
}
else
{
PushDown(cur->rs, f, mid + 1, treer);
}
}
}
if (f(mid) < cur->f(mid))cur->f = f;
}
void Add(Tree*& cur, int l, int r, Function f, int treel, int treer)
{
if (cur == NULL)cur = new Tree;
if (l <= treel && treer <= r)
{
PushDown(cur, f, treel, treer);
}
else
{
int mid = (treel + treer) >> 1;
if (l <= mid)Add(cur->ls, l, r, f, treel, mid + 0);
if (mid < r) Add(cur->rs, l, r, f, mid + 1, treer);
}
}
int Ask(Tree* cur, int x, int treel, int treer)
{
int res = +INF;
if (cur != NULL)
{
res = cur->f(x);
if (treel != treer)
{
int mid = (treel + treer) >> 1;
if (x <= mid)res = min(res, Ask(cur->ls, x, treel, mid + 0));
if (mid < x) res = min(res, Ask(cur->rs, x, mid + 1, treer));
}
}
return res;
}
public:
C_LiChaoTree(void)
{
root = NULL, treel = treer = 0;
}
~C_LiChaoTree(void)
{
if (root != NULL)
{
queue<Tree*>q; q.push(root);
while (!q.empty())
{
if (q.front()->ls != NULL)q.push(q.front()->ls);
if (q.front()->rs != NULL)q.push(q.front()->rs);
delete q.front(); q.pop();
}
}
}
/*====================*/
void Init(int treel, int treer)
{
this->treel = treel;
this->treer = treer;
}
void operator()(int l, int r, Function f)
{
Add(root, l, r, f, treel, treer);
}
int operator[](int x)
{
return Ask(root, x, treel, treer);
}
};
可持久化01Trie
int root[N], tot;
int siz[35 * N];
int trie[35 * N][2];
/*====================*/
void Insert(int pre, int cur, lnt num)
{
for (int i = 32; i >= 0; --i)
{
siz[cur] = siz[pre] + 1;
int bit = (num & (1ll << i)) ? 1 : 0;
trie[cur][bit ^ 1] = trie[pre][bit ^ 1], trie[cur][bit] = ++tot;
pre = trie[pre][bit]; cur = trie[cur][bit];
}
siz[cur] = siz[pre] + 1;
}
lnt Query(int cur, lnt num, int k)
{
lnt ans = 0;
for (int i = 32; i >= 0; --i)
{
int bit = (num & (1ll << i)) ? 1 : 0;
if (siz[trie[cur][bit ^ 1]] >= k)
{
ans += 1ll << i;
cur = trie[cur][bit ^ 1];
}
else
{
k -= siz[trie[cur][bit ^ 1]];
cur = trie[cur][bit];
}
}
return ans;
}
Treap维护珂朵莉树
namespace Treap
{
struct Node
{
Range range;
int priority;
int lch, rch;
}node[N * 4];
/*====================*/
int null = -1;
int root = -1;
/*====================*/
int Creat(Range range)
{
static int cnt = 0; ++cnt;
node[cnt].lch = null;
node[cnt].rch = null;
node[cnt].priority = rand();
node[cnt].range = range;
return cnt;
}
/*====================*/
void PushUp(int cur)
{
node[cur].range.L = node[cur].range.l;
node[cur].range.R = node[cur].range.r;
node[cur].range.Sum = node[cur].range.sum();
if (node[cur].lch != null)
{
node[cur].range.L = node[node[cur].lch].range.L;
node[cur].range.Sum += node[node[cur].lch].range.Sum;
}
if (node[cur].rch != null)
{
node[cur].range.R = node[node[cur].rch].range.R;
node[cur].range.Sum += node[node[cur].rch].range.Sum;
}
}
void PushDown(int cur)
{
if (node[cur].range.lazy != 0)
{
if (node[cur].lch != null)
{
node[node[cur].lch].range.Maintain(node[cur].range.lazy);
}
if (node[cur].rch != null)
{
node[node[cur].rch].range.Maintain(node[cur].range.lazy);
}
node[cur].range.lazy = 0;
}
}
/*====================*/
int Merge(int ltree, int rtree)
{
if (ltree == null)return rtree;
if (rtree == null)return ltree;
PushDown(ltree); PushDown(rtree);
if (node[ltree].priority < node[rtree].priority)
{
node[rtree].lch = Merge(ltree, node[rtree].lch);
/*======*/PushUp(rtree); return rtree;
}
else
{
node[ltree].rch = Merge(node[ltree].rch, rtree);
/*======*/PushUp(ltree); return ltree;
}
}
/*====================*/
void Lower_Split(int cur, unt index, int& ltree, int& rtree)//index留在rtree
{
if (cur == null)
{
ltree = rtree = null; return;
}
PushDown(cur);
if (node[cur].range.r < index)
{
Lower_Split(node[cur].rch, index, ltree, rtree);
node[cur].rch = ltree; PushUp(cur); ltree = cur;
}
else
{
Lower_Split(node[cur].lch, index, ltree, rtree);
node[cur].lch = rtree; PushUp(cur); rtree = cur;
}
}
void Upper_Split(int cur, unt index, int& ltree, int& rtree)//index留在ltree
{
if (cur == null)
{
ltree = rtree = null; return;
}
PushDown(cur);
if (node[cur].range.l > index)
{
Upper_Split(node[cur].lch, index, ltree, rtree);
node[cur].lch = rtree; PushUp(cur); rtree = cur;
}
else
{
Upper_Split(node[cur].rch, index, ltree, rtree);
node[cur].rch = ltree; PushUp(cur); ltree = cur;
}
}
/*====================*/
void SplitL(int root, unt index, int& ltree, int& rtree)
{
int _temp, _ltree, _mtree, _rtree;
Upper_Split(root, index, _temp, _rtree);
Lower_Split(_temp, index, _ltree, _mtree);
unt l = node[_mtree].range.l;
unt r = node[_mtree].range.r;
unt val = node[_mtree].range.val;
if (l != index)
{
ltree = Merge(_ltree, Creat(Range(l, index - 1, val)));
rtree = Merge(Creat(Range(index + 0, r, val)), _rtree);
}
else
{
ltree = _ltree;
rtree = Merge(_mtree, _rtree);
}
}
void SplitR(int root, unt index, int& ltree, int& rtree)
{
int _temp, _ltree, _mtree, _rtree;
Upper_Split(root, index, _temp, _rtree);
Lower_Split(_temp, index, _ltree, _mtree);
unt l = node[_mtree].range.l;
unt r = node[_mtree].range.r;
unt val = node[_mtree].range.val;
if (r != index)
{
ltree = Merge(_ltree, Creat(Range(l, index + 0, val)));
rtree = Merge(Creat(Range(index + 1, r, val)), _rtree);
}
else
{
ltree = Merge(_ltree, _mtree);
rtree = _rtree;
}
}
}
动态开点权值线段树
class C_SegmentTree
{
private:
struct Tree
{
int siz;
Tree* ls, * rs;
Tree(void)
{
siz = 0; ls = rs = NULL;
}
};
/*====================*/
Tree* null;
/*====================*/
Tree* root; int treel, treer;
/*====================*/
Tree* Creat(int siz = 0)
{
Tree* cur = new Tree;
cur->siz = siz; cur->ls = cur->rs = null;
return cur;
}
/*====================*/
void Change(Tree*& cur, int valu, int delta, int treel, int treer)
{
if (cur == null)cur = Creat();
cur->siz += delta;
if (treel != treer)
{
int mid = (treel + treer) >> 1;
if (valu <= mid)Change(cur->ls, valu, delta, treel, mid + 0);
if (mid < valu) Change(cur->rs, valu, delta, mid + 1, treer);
}
}
/*====================*/
int GetValuByRank(Tree* cur, int rank, int treel, int treer)
{
if (treel == treer)
{
return treel;
}
else
{
int mid = (treel + treer) >> 1;
if (cur->ls->siz >= rank)
{
return GetValuByRank(cur->ls, rank, treel, mid + 0);
}
else
{
return GetValuByRank(cur->rs, rank - cur->ls->siz, mid + 1, treer);
}
}
}
int GetRankByValu(Tree* cur, int valu, int treel, int treer)
{
if (cur == null)
{
return 0;
}
else
{
if (treer < valu)
{
return cur->siz;
}
else
{
int res = 0;
int mid = (treel + treer) >> 1;
res += GetRankByValu(cur->ls, valu, treel, mid + 0);
if (mid + 1 < valu) res += GetRankByValu(cur->rs, valu, mid + 1, treer);
return res;
}
}
}
public:
C_SegmentTree(void)
{
root = null = new Tree; treel = treer = 0;
}
~C_SegmentTree(void)
{
if (root != null)
{
queue<Tree*>q; q.push(root);
while (!q.empty())
{
if (q.front()->ls != null)q.push(q.front()->ls);
if (q.front()->rs != null)q.push(q.front()->rs);
delete q.front(); q.pop();
}
}
delete null;
}
/*====================*/
int Size(void)
{
return root->siz;
}
bool Empty(void)
{
return root->siz == 0;
}
void Init(int treel, int treer)
{
this->treel = treel; this->treer = treer;
}
void Erase(int valu)
{
Change(root, valu, -1, treel, treer);
}
void Insert(int valu)
{
Change(root, valu, +1, treel, treer);
}
int operator[](int rank)
{
return GetValuByRank(root, rank, treel, treer);
}
int operator()(int valu)
{
return GetRankByValu(root, valu, treel, treer) + 1;
}
};
标签:null,return,cur,val,int,tree,数据结构
From: https://www.cnblogs.com/ProtectEMmm/p/18360927