首页 > 其他分享 >数据结构

数据结构

时间:2024-08-15 15:09:34浏览次数:9  
标签:null return cur val int tree 数据结构

数据结构

莫队

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

相关文章

  • 【数据结构】TreeMap和TreeSet
    目录前言TreeMap实现的接口内部类常用方法TreeSet实现的接口常用方法前言Map和set是一种专门用来进行搜索的容器或者数据结构,其搜索的效率与其具体的实例化子类有关。一般把搜索的数据称为关键字(Key),和关键字对应的称为值(Value),将其称之为Key-value的键值对。......
  • 知识改变命运 数据结构【顺序表】
    1.线性表线性表(linearlist)是n个具有相同特性的数据元素的有限序列。线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列…线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组......
  • 高阶数据结构(Java):AVL树插入机制的探索
    目录1、概念1.1什么是AVL树2.1平衡因子3、AVL树节点的定义4、AVL树的插入机制4.1初步插入节点4.2更新平衡因子4.3 提升右树高度4.3.1右单旋4.3.2左右双旋4.4 提升左树高度4.4.1左单旋 4.4.2右左双旋5、AVL树的验证6、AVL树的删除1、概念1.1什......
  • 【数据结构】详细介绍线性表中的顺序表,带你复盘实现细节,附上顺序表编程练习题
    目录一.线性表二.顺序表 1.静态顺序表与动态顺序表2.动态顺序表的接口实现 2.1顺序表初始化 2.2判断是否需要扩容  2.3 顺序表指定位置插入2.4 顺序表头插2.5 顺序表尾插2.6 顺序表指定位置删除2.7 顺序表头删2.8 顺序表尾删2.9 顺序表查找2.1......
  • 数据结构之链表超详解(1)
     一人我饮酒醉醉把佳人成双对两眼是独相随只求他日能双归娇女我轻扶琴燕嬉我紫竹林痴情红颜心甘情愿千里把你寻说红颜我痴情笑曲动我琴声妙轻狂高傲懵懂无知只怪太年少弃江山我忘天下斩断情丝无牵挂千古留名传佳话我两年征战已白发一生征战何人陪谁是谁非谁相随戎马一......
  • 一次函数最优化数据结构
    哎呀没写完,明天再补吧李超线段树一个节点维护递归到这个点,包含整个区间,并且在mid处取值最大的线段。若有两条线段,其中x比y在mid处值更大,如果x在l和r处值都比y大,显然y没有用。否则y只可能在左区间或右区间比x优。李超线段树利用单侧递归保证时间复杂度。但是李超线段树不便于......
  • 嵌入式软件--数据结构与算法 DAY 12
    数据结构和算法是程序的核心,虽然在嵌入式应用中很少会用到,但了解认知这种思维过程是非常有必要的。一个好的程序员应该把数据结构和算法看的比代码更重要。1.数据结构是什么?定义1(宏观):数据结构是为了高效访问数据而设计出的一种数据的组织和存储方式。定义2(微观):数据结构......
  • 嵌入式软件--数据结构与算法 DAY 13
    在嵌入式中,对算法的要求不高,但顺序查找和冒泡排序是经典算法,必须掌握。1.算法定义算法是一个用于解决特定问题的有限指令序列(计算机可以执行的操作)。通俗的理解就是可以解决特定问题的方法。2.时间复杂度时间复杂度不是执行完一段程序的总时间,而是描述为一个算法中基本操作......
  • [OI] 可持久化数据结构
    学了一年OI才看懂这句话:\(\logn\)是以什么为底的?其实没什么区别因为我们自动忽略常数,因此\(\log_{a}n=\frac{\log_{x}n}{\log_{x}a}=\log_{x}n\)可持久化数组可持久化数组是基于可持久化线段树的一种数据结构.它可以支持如下操作:单点修改查询历史版本在历史版......
  • 25版王道数据结构课后习题详细分析 第五章 树与二叉树 5.1 树的基本概念
     一、单项选择题————————————————————————————————————————解析:树是一种分层结构,它特别适合组织那些具有分支层次关系的数据。正确答案:D————————————————————————————————————————解......