平衡树做题记录

板子就不说了。

P2786 英语1(eng1)- 英语作文

红黑树 map 随便做,用一个 map 存下字符串对应的值,一个字符一个字符读入,然后判断, 如果不是数字并且不是字母,说明空格或者符号,处理答案。

/**
 *	author: TLE_Automation
 *	creater: 2022.9.7
 **/
#include<cmath>
#include<queue>
#include<cstdio>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
#define gc getchar 
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
const int mod = 998244353;
const ll inf = 0x3f3f3f3f3f3f3f3f;
#define debug cout << "i ak ioi" << "\n"
inline void print(int x) {if (x < 0) putchar('-'), x = -x; if(x > 9) print(x / 10); putchar(x % 10 + '0');}
inline char readchar() {static char buf[100000], *p1 = buf, *p2 = buf; return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++;}
inline int read() { int res = 0, f = 0; char ch = gc();for (; !isdigit(ch); ch = gc()) f |= (ch == '-'); for (; isdigit(ch); ch = gc()) res = (res << 1) + (res << 3) + (ch ^ '0'); return f ? -res : res;}

#include <unordered_map>

int n, p, ans;
char ch; string t;
unordered_map <string, int> mp;
signed main() 	
{
	n = read(), p = read();
	for(int i = 1; i <= n; i++) {
		string s; cin >> s; mp[s] = read();
	}
	while((ch = getchar()) && ch != EOF) {
		if(!isdigit(ch) && !isalpha(ch)) ans = (ans + mp[t]) % p, t = "";
		else t += ch;
	}
	printf("%d\n", ans);
	return (0 - 0);
}

P1503 鬼子进村

用平衡树来维护被毁坏的房子,权值即为编号,用一个栈来取最后被毁坏的房子。

最后查询答案的时候就是 \(nxt - pre - 1\)


/**
 *	author: TLE_Automation
 *	creater: 2022.9.7
 **/
#include<cmath>
#include<queue>
#include<random>
#include<cstdio>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
#define gc getchar 
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
const int mod = 998244353;
const ll inf = 0x3f3f3f3f3f3f3f3f;
#define debug cout << "i ak ioi" << "\n"
inline void print(int x) {if (x < 0) putchar('-'), x = -x; if(x > 9) print(x / 10); putchar(x % 10 + '0');}
inline char readchar() {static char buf[100000], *p1 = buf, *p2 = buf; return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++;}
inline int read() { int res = 0, f = 0; char ch = gc();for (; !isdigit(ch); ch = gc()) f |= (ch == '-'); for (; isdigit(ch); ch = gc()) res = (res << 1) + (res << 3) + (ch ^ '0'); return f ? -res : res;}

int root, idx, x, y, z, res;
std::mt19937 rnd(114514);

namespace FHQ_Treap {
	#define ls(x) tr[x].ls
	#define rs(x) tr[x].rs
	struct Node {int ls, rs, siz, val, key;} tr[N];
	inline int newnode(int v) {int x = rnd(); tr[++idx] = (Node) {0, 0, 1, v, x}; return idx;}
	inline void pushup(int p) {tr[p].siz = tr[ls(p)].siz + tr[rs(p)].siz + 1; }
	inline void split(int p, int v, int &x, int &y) {
		if(!p) {x = y = 0; return;}
		if(tr[p].val <= v) x = p, split(rs(x), v, rs(x), y);
		else y = p, split(ls(y), v, x, ls(y)); 
		pushup(p);
	}
	inline int merge(int x, int y) {
		if(!x || !y) return x + y;
		if(tr[x].key < tr[y].key) { rs(x) = merge(rs(x), y), pushup(x); return x;}
		else {ls(y) = merge(x, ls(y)), pushup(y); return y; }
	}
	inline void Insert(int v) {
		split(root, v, x, y), z = newnode(v), root = merge(merge(x, z), y);
	}
	inline void del(int v) {
		split(root, v, x, z), split(x, v - 1, x, y), y = merge(ls(y), rs(y)), root = merge(merge(x, y), z);
	}
	inline int getnum(int p, int k) {
		if(tr[ls(p)].siz >= k) return getnum(ls(p), k);
		if(tr[ls(p)].siz + 1 == k) return p;
		return getnum(rs(p), k - tr[ls(p)].siz - 1);
	}
	inline int getpre(int v) {
		split(root, v - 1, x, y), res = getnum(x, tr[x].siz), root = merge(x, y); return tr[res].val;
	}
	inline int getnxt(int v) {
		split(root, v, x, y), res = getnum(y, 1), root = merge(x, y); return tr[res].val;
	}
}
using namespace FHQ_Treap;

bitset <N> vis;
int stc[N], sc = 0;

signed main() 	
{
	int n = read(), m = read();
	Insert(0), Insert(n + 1);
	for(int i = 1; i <= m; i++)	{
		char ch; cin >> ch;
		if(ch == 'D') {
			int x = read();
			vis[x] = 1; stc[++sc] = x;
			Insert(x);
		}
		else if(ch == 'R') {
			vis[stc[sc]] = 0; 
			del(stc[sc--]);
		}
		else {
			int x = read();
			if(vis[x]) {puts("0"); continue;}
			printf("%d\n", getnxt(x) - getpre(x) - 1);
		}
	}
	return (0 - 0);
}

P3871 [TJOI2010]中位数

很明显的平衡树啊,随便敲敲就过了。

用一个 \(cnt\) 来维护当前平衡树中插入的数量,查询的时候分奇数偶数查询中位数即可。

/**
 *	author: TLE_Automation
 *	creater: 2022.9.7
 **/
#include<cmath>
#include<queue>
#include<random>
#include<cstdio>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
#define gc getchar 
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
const int mod = 998244353;
const ll inf = 0x3f3f3f3f3f3f3f3f;
#define debug cout << "i ak ioi" << "\n"
inline void print(int x) {if (x < 0) putchar('-'), x = -x; if(x > 9) print(x / 10); putchar(x % 10 + '0');}
inline char readchar() {static char buf[100000], *p1 = buf, *p2 = buf; return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++;}
inline int read() { int res = 0, f = 0; char ch = gc();for (; !isdigit(ch); ch = gc()) f |= (ch == '-'); for (; isdigit(ch); ch = gc()) res = (res << 1) + (res << 3) + (ch ^ '0'); return f ? -res : res;}

int root, idx, x, y, z;
std::mt19937 rnd(114514);

namespace FHQ_Treap {
	#define ls(x) tr[x].ls
	#define rs(x) tr[x].rs
	struct Node {int ls, rs, val, siz, key; } tr[N];
	inline int newnode (int v) {int x = rnd(); tr[++idx] = (Node) {0, 0, v, 1, x}; return idx; }
	inline void pushup (int p) {tr[p].siz = tr[ls(p)].siz + tr[rs(p)].siz + 1; }
	inline void split(int p, int v, int &x, int &y) {
		if(!p) {x = y = 0; return; }
		if(tr[p].val <= v) x = p, split(rs(x), v, rs(x), y);
		else y = p, split(ls(y), v, x, ls(y)); 
		pushup(p);
	} 
	inline int merge(int x, int y) {
		if(!x || !y) return x + y;
		if(tr[x].key < tr[y].key) { rs(x) = merge(rs(x), y); pushup(x); return x;}
		else {ls(y) = merge(x, ls(y)); pushup(y); return y; }
	}
	inline void Insert(int v) {
		split(root, v, x, y); z = newnode(v), root = merge(merge(x, z), y);
	}
	inline int getnum(int p, int k) {
		if(tr[ls(p)].siz >= k) return getnum(ls(p), k);
		else if(tr[ls(p)].siz + 1 == k) return p;
		return getnum(rs(p), k - tr[ls(p)].siz - 1);
	}
}
using namespace FHQ_Treap;

int cnt = 0;

signed main() 	
{
	int n = read();
	for(int i = 1; i <= n; i++) {
		int o = read(); Insert(o);
		cnt++;
	}
	int m = read();
	for(int i = 1; i <= m; i++) {
		string s; cin >> s;
		if(s == "add") {
			int o = read(); Insert(o);
			cnt++;
		}
		else {
			if(cnt & 1) printf("%d\n", tr[getnum(root, cnt / 2 + 1)].val);
			else {
				printf("%d\n", std::min(tr[getnum(root, cnt / 2)].val, tr[getnum(root, cnt / 2 + 1)].val));
			}
		}
	}
	return (0 - 0);
}

P2286 [HNOI2004]宠物收养场

平衡树模板,维护一个 cnt,记录当前是宠物树还是顾客树即可。

/**
 *	author: TLE_Automation
 *	creater: 2022.9.7
 **/
#include<cmath>
#include<queue>
#include<random>
#include<cstdio>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
#define gc getchar 
using namespace std;
typedef long long ll;
#define int long long
const int N = 1e6 + 10;
const int mod = 1000000;
const ll inf = 0x3f3f3f3f3f3f3f3f;
#define debug cout << "i ak ioi" << "\n"
inline void print(int x) {if (x < 0) putchar('-'), x = -x; if(x > 9) print(x / 10); putchar(x % 10 + '0');}
inline char readchar() {static char buf[100000], *p1 = buf, *p2 = buf; return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++;}
inline int read() { int res = 0, f = 0; char ch = gc();for (; !isdigit(ch); ch = gc()) f |= (ch == '-'); for (; isdigit(ch); ch = gc()) res = (res << 1) + (res << 3) + (ch ^ '0'); return f ? -res : res;}

std::mt19937 rnd(114514);

int x, y, z, root, idx = 0, res;

namespace FHQ_Treap {
	#define ls(x) tr[x].ls
	#define rs(x) tr[x].rs
	struct Node { int ls, rs, val, siz, key;} tr[N << 2];
	inline int newnode(int v) { int x = rnd(); tr[++idx] = (Node) {0, 0, v, 1, x}; return idx;}
	inline void pushup(int p) {tr[p].siz = tr[ls(p)].siz + tr[rs(p)].siz + 1;}
	inline void split(int p, int v, int &x, int &y) {
		if(!p) {x = y = 0; return;}
		if(tr[p].val <= v) x = p, split(rs(x), v, rs(x), y);
		else y = p, split(ls(y), v, x, ls(y)); 
		pushup(p);
	}
	inline int merge(int x, int y) {
		if(!x || !y) return x + y;
		if(tr[x].key < tr[y].key) {	rs(x) = merge(rs(x), y); pushup(x); return x;}
		else {ls(y) = merge(x, ls(y)), pushup(y); return y; }
	}
	inline void Insert(int v) {
		split(root, v, x, y); z = newnode(v), root = merge(merge(x, z), y);
	}
	inline void del(int v) {
		split(root, v, x, z), split(x, v - 1, x, y), y = merge(ls(y), rs(y)); root = merge(merge(x, y), z);
	}
	inline int getnum(int p, int k) {
		if(tr[ls(p)].siz >= k) return getnum(ls(p), k);
		else if(tr[ls(p)].siz + 1 == k) return p;
		else return getnum(rs(p), k - tr[ls(p)].siz - 1);
	}
	inline int getpre(int v) {
		split(root, v - 1, x, y), res = getnum(x, tr[x].siz), root = merge(x, y); return tr[res].val;
	}
	inline int getnxt(int v) {
		split(root, v, x, y), res = getnum(y, 1), root = merge(x, y);  return tr[res].val;
	}
}
using namespace FHQ_Treap;

int flag = 0;
ll ans;

signed main() {
	int n = read();
	Insert(0x3f3f3f3f), Insert(-0x3f3f3f3f);
	for (int i = 1; i <= n; ++i) {
		int a = read(), b = read();
		if (flag == 0) Insert(b);
		else if (flag < 0) {
			if (!a) Insert(b);
			else {
				ll pick1 = getpre(b), pick2 = getnxt(b);
				if (pick2 - b < b - pick1) del(pick2), (ans += pick2 - b) %= 1000000;
				else del(pick1), (ans += b - pick1) %= 1000000;
			}
		} else if (flag > 0) {
			if (a) Insert(b);
			else {
				ll pick1 = getpre(b), pick2 = getnxt(b);
				if (pick2 - b < b - pick1) del(pick2), (ans += pick2 - b) %= 1000000;
				else del(pick1), (ans += b - pick1) %= 1000000;
			}
		}
		flag += 1 * (a ? 1 : -1);
	}
	printf("%lld\n", ans);
	return 0;
}

P1486 [NOI2004] 郁闷的出纳员

用一个 \(tag\) 维护全局加的值,当插入一个数的时候,为了除去之前给的贡献,减去一个 tag,因为后面还会加上。

这里是分裂成 \(<x\)\(>= x\) 的两颗子树。

/**
 *	author: TLE_Automation
 *	creater: 2022.9.7
 **/
#include<cmath>
#include<queue>
#include<cstdio>
#include<random>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
#define gc getchar 
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
const int mod = 998244353;
const ll inf = 0x3f3f3f3f3f3f3f3f;
#define debug cout << "i ak ioi" << "\n"
inline void print(int x) {if (x < 0) putchar('-'), x = -x; if(x > 9) print(x / 10); putchar(x % 10 + '0');}
inline char readchar() {static char buf[100000], *p1 = buf, *p2 = buf; return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++;}
inline int read() { int res = 0, f = 0; char ch = gc();for (; !isdigit(ch); ch = gc()) f |= (ch == '-'); for (; isdigit(ch); ch = gc()) res = (res << 1) + (res << 3) + (ch ^ '0'); return f ? -res : res;}

int root, x, y, z, idx = 0, cnt = 0, n, Min, ans = 0;
std::mt19937 rnd(114514);

namespace FHQ_Treap {
	#define ls(x) tr[x].ls
	#define rs(x) tr[x].rs
	struct Node {int ls, rs, val, siz, key; } tr[N];	
	inline int newnode(int v) {int x = rnd(); tr[++idx] = (Node) {0, 0, v, 1, x}; return idx;}
	inline void pushup(int p) {tr[p].siz = tr[ls(p)].siz + tr[rs(p)].siz + 1; }
	inline void split(int p, int v, int &x, int &y) {
		if(!p) {x = y = 0; return ;}
		if(tr[p].val < v) x = p, split(rs(x), v, rs(x), y);
		else y = p, split(ls(y), v, x, ls(y));
		pushup(p);
	}
	inline int merge(int x, int y) {
		if(!x || !y) return x + y;
		if(tr[x].key <tr[y].key) { rs(x) = merge(rs(x), y); pushup(x); return x;}
		else {ls(y) = merge(x, ls(y)); pushup(y); return y;}
	}
	inline void Insert(int v) {
		split(root, v, x, y), z = newnode(v), root = merge(merge(x, z), y);
	}
	inline void del(int v) {
		split(root, v, x, z), split(x, v - 1, x, y), y = merge(ls(y), rs(y)); root = merge(merge(x, y), z);
	}
	inline int getnum(int p, int k) {
		if(tr[ls(p)].siz >= k) return getnum(ls(p), k);
		if(tr[ls(p)].siz + 1 == k) return p;
		return getnum(rs(p), k - tr[ls(p)].siz - 1);
	}
	inline void leave() {
		split(root, Min - cnt, x, y);
		ans += tr[x].siz; root = y;
	}
}

using namespace FHQ_Treap;

signed main() 	
{
	n = read(), Min = read();
	for(int i = 1; i <= n; i++) {
		char ch; cin >> ch; int k = read();
		if(ch == 'I') {
			if(k >= Min) Insert(k - cnt);
		}
		else if(ch == 'A') cnt += k;
		else if(ch == 'S') cnt -= k, leave();
		else if(ch == 'F') printf("%d\n", k <= tr[root].siz ? tr[getnum(root, tr[root].siz - k + 1)].val + cnt : -1);
		// cout << "##" << i << " " << cnt << " " << ans << "\n";
	}
	printf("%d\n", ans);
	return (0 - 0);
}

P2343 宝石管理系统

插入和求 \(k\) 大, 纯纯的板子,太好写了。

/**
 *	author: TLE_Automation
 *	creater: 2022.9.7
 **/
#include<cmath>
#include<queue>
#include<cstdio>
#include<random>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
#define gc getchar 
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
const int mod = 998244353;
const ll inf = 0x3f3f3f3f3f3f3f3f;
#define debug cout << "i ak ioi" << "\n"
inline void print(int x) {if (x < 0) putchar('-'), x = -x; if(x > 9) print(x / 10); putchar(x % 10 + '0');}
inline char readchar() {static char buf[100000], *p1 = buf, *p2 = buf; return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++;}
inline int read() { int res = 0, f = 0; char ch = gc();for (; !isdigit(ch); ch = gc()) f |= (ch == '-'); for (; isdigit(ch); ch = gc()) res = (res << 1) + (res << 3) + (ch ^ '0'); return f ? -res : res;}

std::mt19937 rnd(114514);
int root, x, y, z, idx = 0;

namespace FHQ_Treap {
	#define ls(x) tr[x].ls
	#define rs(x) tr[x].rs
	struct Node {int ls, rs, val, siz, key; } tr[N];
	inline int newnode(int v) {int x = rnd(); tr[++idx] = (Node) {0, 0, v, 1, x}; return idx; }
	inline void pushup(int p) {tr[p].siz = tr[ls(p)].siz + tr[rs(p)].siz + 1; }
	inline void split(int p, int v, int &x, int &y) {
		if(!p) {x = y = 0; return; }
		if(tr[p].val <= v) x = p, split(rs(x), v, rs(x), y);
		else y = p, split(ls(y), v, x, ls(y)); 
		pushup(p); 
	}
	inline int merge(int x, int y) {
		if(!x || !y) return x + y;
		if(tr[x].key < tr[y].key) {rs(x) = merge(rs(x), y), pushup(x); return x;}
		else {ls(y) = merge(x, ls(y)); pushup(y); return y; }
	}
	inline void Insert(int v) {
		split(root, v, x, y), root = merge(merge(x, newnode(v)), y);
	}
	inline int getnum(int p, int k) {
		if(tr[ls(p)].siz >= k) return getnum(ls(p), k);
		if(tr[ls(p)].siz + 1 == k) return p;
		return getnum(rs(p), k - tr[ls(p)].siz - 1);
	}
}
using namespace FHQ_Treap;

signed main() 	
{
	int n = read(), m = read();
	for(int i = 1; i <= n; i++) x = read(), Insert(x);
	while(m--) {
		int opt = read(), k = read();
		if(opt & 1) printf("%d\n", tr[getnum(root, tr[root].siz - k + 1)].val);
		else Insert(k);
	} 	
	return (0 - 0);
}


posted @ 2022-09-08 08:24  TLE_Automation  阅读(31)  评论(0编辑  收藏  举报