本文共 3746 字,大约阅读时间需要 12 分钟。
在这篇文章中,我将详细描述如何设计和实现一个高效的工资统计系统。这将帮助我们处理公司员工的工资调整和查询需求。系统将支持四种命令:新增员工、调整工资、查询工资和统计员工离开总数。由于频繁的工资调整和查询操作,我们将使用高效的数据结构来确保系统性能。
为了处理频繁的插入、删除和查询操作,我们选择使用平衡二叉搜索树(AVL树)。每个节点将存储以下信息:
#include#include #include #define MAXN 300000using namespace std;int Cnt[MAXN]; // 节点计数int Size[MAXN]; // 节点数量int Key[MAXN]; // 节点的键值int Son[MAXN][2]; // 左、右子树int Father[MAXN]; // 父节点int SIZE = 1, ROOT = 0;void Clear(int x) { Cnt[x] = Size[x] = Key[x] = 0; Son[x][0] = Son[x][1] = 0; Father[x] = 0; Update(x);}int Get(int x) { return (Son[Father[x]][1] == x);}void Update(int x) { if (x == 0) return; Size[x] = Cnt[x]; if (Son[x][1]) Size[x] += Size[Son[x][1]]; if (Son[x][0]) Size[x] += Size[Son[x][0]];}void Rotate(int x) { int fa = Father[x]; int fafa = Father[fa]; int wh = Get(x); Son[fa][wh] = Son[x][wh ^ 1]; Father[fa] = x; if (Son[fa][wh]) Father[Son[fa][wh]] = fa; Father[x] = fafa; Son[x][wh ^ 1] = fa; if (fafa) Son[fafa][Son[fafa][1] == fa] = x; Update(fa); Update(x);}void Splay(int x) { for (int fa = Father[x]; fa; Rotate(x)) { if (Father[fa]) Rotate(Get(fa) == Get(x) ? fa : x); } ROOT = x;}int Findx(int k) { int now = ROOT; while (true) { if (k > Size[Son[now][0]]) { now = Son[now][0]; } else { k -= Size[Son[now][0]]; if (k <= Cnt[now]) { Splay(now); return Key[now]; } k -= Cnt[now]; now = Son[now][1]; } }}void Insert(int x) { if (ROOT == 0) { ROOT = SIZE++; Key[ROOT] = x; Cnt[ROOT] = Size[ROOT] = 1; return; } int now = ROOT, fa = 0; while (true) { if (Key[now] == x) { Cnt[now]++; Update(now); Splay(now); return; } fa = now; now = Son[now][x > Key[now]]; if (now == 0) { SIZE++; Key[SIZE] = x; Cnt[SIZE] = Size[SIZE] = 1; Father[SIZE] = fa; Son[fa][x > Key[fa]] = SIZE; Update(fa); Splay(SIZE); return; } }}int main() { int delta = 0, n, min, x, Sum = 0, Ans = 0; char p; scanf("%d %d", &n, &min); for (int i = 1; i <= n; ++i) { Insert(min - delta - 1); Sum += Size[Son[ROOT][0]] + Cnt[ROOT] - 1; Ans += Size[Son[ROOT][0]] + Cnt[ROOT] - 1; int old_root = ROOT; Father[Son[ROOT][1]] = 0; ROOT = Son[ROOT][1]; Clear(old_root); scanf("%c %d", &p, &x); if (p == 'A') delta += x; else if (p == 'S') delta -= x; else if (p == 'I') { if (x - delta >= min - delta) { Insert(x - delta); Sum++; } } else if (p == 'F') { if (Sum >= x) { int pos = Sum - x + 1; if (pos > Cnt[ROOT]) { printf(-1); } else { int res = Findx(pos); printf(res + delta); } } else { printf(-1); } } } printf(Ans);}
Insert
函数将新员工插入到正确的位置,保持树的平衡。Rotate
和Splay
函数用于保持树的平衡,确保查找和插入操作的高效性。Findx
函数根据当前根节点,逐步向下调整,找到第k大的工资值。main
函数中,逐条处理命令,更新工资调整量delta,并根据命令类型执行相应的操作。通过使用平衡二叉搜索树,我们可以高效地处理插入、删除和查询操作,确保系统在处理大量数据时依然保持高效性能。这种设计能够满足题目中的需求,确保每条命令都能被快速处理。
转载地址:http://lsgfk.baihongyu.com/