Codeforces Round #457 (Div. 2) D. Jamie and To-do List 主席树
Posted kaka0010
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #457 (Div. 2) D. Jamie and To-do List 主席树相关的知识,希望对你有一定的参考价值。
原题链接:https://codeforces.ml/contest/916/problem/D
题意
有四个操作
- set 将x的优先级修改为y
- remove 将x这个数移除
- query 查询有多少数小于x的优先级
- undo 撤销x次操作
分析
看到撤销操作应该就知道这是个主席树的题了,但撤销时需要维护两个信息,一个是相同优先级的数有几个,还有一个是当前这个数的优先级是多少,因此必须建两颗主席树,别的操作按照题意来就可以了,比较基础的主席树练习。太久没写主席了,手写错了一遍 ,下次还是得小心。
Code
#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define re register
typedef long long ll;
typedef pair<ll, ll> PII;
typedef unsigned long long ull;
const int N = 1e5 + 10, M = 1e6 + 5, INF = 0x3f3f3f3f;
const int MOD = 1e9+7;
int rt1[N * 100], rt2[N * 100], sum[N * 100], ls[N * 100], rs[N * 100], cnt;
void modify(int &now, int pre, int l, int r, int pos, int val) {
now = ++cnt;
ls[now] = ls[pre], rs[now] = rs[pre], sum[now] = sum[pre] + val;
if (l == r) return;
int mid = (l + r) >> 1;
if (pos <= mid) modify(ls[now], ls[pre], l, mid, pos, val);
else modify(rs[now], rs[pre], mid+1, r, pos, val);
}
int query(int now, int l, int r, int ql, int qr) {
if (ql <= l && qr >= r) return sum[now];
int mid = (l + r) >> 1;
int ans = 0;
if (ql <= mid) ans += query(ls[now], l, mid, ql, qr);
if (qr > mid) ans += query(rs[now], mid+1, r, ql, qr);
return ans;
}
map<string, int> id;
int tot;
int getid(string s) {
if (id.find(s) == id.end()) {
id[s] = ++tot;
return tot;
}
else return id[s];
}
void solve() {
int n; cin >> n;
for (int i = 1; i <= n; i++) {
string opt, name; int priority;
cin >> opt;
rt1[i] = rt1[i-1], rt2[i] = rt2[i-1];
if (opt == "set") {
cin >> name >> priority;
int x = getid(name);
int pre = query(rt2[i], 1, MOD, x, x);
if (!pre) {
modify(rt2[i], rt2[i], 1, MOD, x, priority);
modify(rt1[i], rt1[i], 1, MOD, priority, 1);
} else {
modify(rt2[i], rt2[i], 1, MOD, x, -pre+priority);
modify(rt1[i], rt1[i], 1, MOD, pre, -1);
modify(rt1[i], rt1[i], 1, MOD, priority, 1);
}
} else if (opt == "query") {
cin >> name;
int x = getid(name);
priority = query(rt2[i], 1, MOD, x, x);
if (!priority) cout << -1 << endl;
else if (priority == 1) cout << 0 << endl;
else cout << query(rt1[i], 1, MOD, 1, priority-1) << endl;
fflush(stdout);
} else if (opt == "remove") {
cin >> name;
int x = getid(name);
priority = query(rt2[i], 1, MOD, x, x);
if (!priority) continue;
modify(rt2[i], rt2[i], 1, MOD, x, -priority);
modify(rt1[i], rt1[i], 1, MOD, priority, -1);
} else if (opt == "undo") {
int x; cin >> x;
rt1[i] = rt1[i-x-1], rt2[i] = rt2[i-x-1];
}
}
}
signed main() {
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
#ifdef ACM_LOCAL
freopen("input", "r", stdin);
freopen("output", "w", stdout);
#endif
solve();
return 0;
}
以上是关于Codeforces Round #457 (Div. 2) D. Jamie and To-do List 主席树的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #457 (Div. 2) CJamie and Interesting Graph
Codeforces Round #457 (Div. 2) A Jamie and Alarm Snooze
Codeforces Round #457 (Div. 2) BJamie and Binary Sequence
Codeforces Round #457 (Div. 2) D. Jamie and To-do List 主席树