// Flower_On_Stone
#include <bits/stdc++.h>
using namespace std;
const int MAX_N = 500005;
struct Node {
Node *parent, *children[2];
int label;
int treeSize;
int weight;
int sumWeight;
Node(int label = 0) {
parent = children[0] = children[1] = nullptr;
this->label = label;
treeSize = 1;
weight = 1;
sumWeight = 1;
}
int getDir(Node *a) { return (a == children[0] ? 0 : 1); }
void pushUp() {
treeSize = 1;
sumWeight = weight;
for (int i = 0; i < 2; i++) {
treeSize += (children[i] == nullptr ? 0 : children[i]->treeSize);
sumWeight += (children[i] == nullptr ? 0 : children[i]->sumWeight);
}
}
};
int treeSize(Node *p) { return (p == nullptr ? 0 : p->treeSize); }
int sumWeight(Node *p) { return (p == nullptr ? 0 : p->sumWeight); }
struct SplayTree {
Node *root;
SplayTree(Node *node = nullptr) {
root = node;
if (root != nullptr) {
root->parent = nullptr;
}
}
void link(Node *a, Node *b, int dir) {
if (a == nullptr) {
root = b;
if (root != nullptr) {
root->parent = nullptr;
}
return;
}
a->children[dir] = b;
if (b != nullptr) {
b->parent = a;
}
}
void rotate(Node *a, int dir) {
Node *b = a->children[dir];
Node *p = a->parent;
int parDir = (p == nullptr ? 0 : p->getDir(a));
link(a, b->children[dir ^ 1], dir);
link(b, a, dir ^ 1);
link(p, b, parDir);
}
void splay(Node *a) {
while (a->parent != nullptr) {
int dir = a->parent->getDir(a);
if (a->parent->parent == nullptr) {
rotate(a->parent, dir);
a->children[dir ^ 1]->pushUp();
} else {
int parDir = a->parent->parent->getDir(a->parent);
if (parDir == dir) {
rotate(a->parent->parent, parDir);
rotate(a->parent, dir);
a->children[dir ^ 1]->children[parDir ^ 1]->pushUp();
a->children[dir ^ 1]->pushUp();
} else {
rotate(a->parent, dir);
rotate(a->parent, parDir);
for (int i = 0; i < 2; i++) {
a->children[i]->pushUp();
}
}
}
a->pushUp();
}
}
void find(int pos) {
Node *p = root;
while (true) {
int left = treeSize(p->children[0]);
int mid = 1;
if (left >= pos) {
p = p->children[0];
} else if (left + mid >= pos) {
return splay(p);
} else {
pos -= left + mid;
p = p->children[1];
}
}
}
void findWeight(int pos) {
Node *p = root;
while (true) {
int left = sumWeight(p->children[0]);
int mid = (p->weight);
if (left >= pos) {
p = p->children[0];
} else if (left + mid >= pos) {
return splay(p);
} else {
pos -= left + mid;
p = p->children[1];
}
}
}
int getPos(Node *p) {
splay(p);
return treeSize(root->children[0]) + 1;
}
int getWeight(Node *p) {
splay(p);
return sumWeight(root->children[0]) + p->weight;
}
void merge(SplayTree other) {
if (other.root == nullptr) {
return;
}
if (root == nullptr) {
root = other.root;
return;
}
find(treeSize(root));
link(root, other.root, 1);
root->pushUp();
}
SplayTree split(int pos) {
if (pos > treeSize(root)) {
return SplayTree();
}
if (pos == 1) {
Node *tmp = root;
root = nullptr;
return SplayTree(tmp);
}
find(pos - 1);
Node *tmp = root->children[1];
root->children[1] = nullptr;
tmp->parent = nullptr;
root->pushUp();
return SplayTree(tmp);
}
Node *insert(int label) {
Node *tmp = new Node(label);
merge(SplayTree(tmp));
return tmp;
}
void insert(SplayTree tree, int pos) {
findWeight(pos - 1);
SplayTree tmp = split(getPos(root) + 1);
merge(tree);
merge(tmp);
}
void moveTree(int from, int to) {
SplayTree tmp = split(from + 1);
SplayTree subtree = split(from);
merge(tmp);
tmp = split(to);
merge(subtree);
merge(tmp);
}
int query(int pos) {
find(pos);
return root->label;
}
};
struct SegmentTree {
private:
int treeSize;
vector<int> nodes, leaf;
void initTree(int id, int low, int high, int arr[]) {
if (low == high) {
nodes[id] = arr[low];
leaf[low] = id;
return;
}
int mid = (low + high) / 2;
initTree(id * 2, low, mid, arr);
initTree(id * 2 + 1, mid + 1, high, arr);
nodes[id] = max(nodes[id * 2], nodes[id * 2 + 1]);
}
int get(int id, int low, int high, int left, int right) {
if (low > right || high < left) {
return 0;
}
if (low >= left && high <= right) {
return nodes[id];
}
int mid = (low + high) / 2;
return max(get(id * 2, low, mid, left, right),
get(id * 2 + 1, mid + 1, high, left, right));
}
public:
void init(int treeSize, int arr[]) {
this->treeSize = treeSize;
int tmp = 1;
while (tmp < treeSize) {
tmp *= 2;
}
nodes.resize(tmp * 2);
leaf.resize(treeSize + 1);
initTree(1, 1, treeSize, arr);
}
void update(int id, int value) {
id = leaf[id];
nodes[id] = value;
while (id > 1) {
id /= 2;
nodes[id] = max(nodes[id * 2], nodes[id * 2 + 1]);
}
}
int get(int left, int right) { return get(1, 1, treeSize, left, right); }
} smt;
struct Query {
char type;
int pos, u, v;
Node *uNode, *vNode;
};
int numCake, firstEat, numQuery, maxCake;
int cake[MAX_N];
SplayTree splayTree;
Query queries[MAX_N];
Node *nodes[MAX_N], *initNode[MAX_N];
void buildSplayTree() {
vector<pair<int, int>> tmp(numCake);
for (int i = 1; i <= numCake; i++) {
tmp[i - 1] = make_pair(cake[i], i);
}
sort(tmp.begin(), tmp.end());
splayTree = SplayTree(nullptr);
for (auto &[u, v] : tmp) {
nodes[v] = initNode[v] = splayTree.insert(v);
}
}
void buildQuery() {
for (int i = 1; i <= numQuery; i++) {
if (queries[i].type == 'E') {
queries[i].uNode = nodes[queries[i].pos];
splayTree.getWeight(queries[i].uNode);
splayTree.root->weight = 0;
splayTree.root->pushUp();
queries[i].v = numCake - queries[i].v + 1;
SplayTree tmp = SplayTree();
nodes[queries[i].pos] = queries[i].vNode =
tmp.insert(queries[i].pos);
splayTree.insert(tmp, queries[i].v);
}
}
for (int i = 1; i <= numQuery; i++) {
if (queries[i].type == 'E') {
queries[i].u = splayTree.getPos(queries[i].uNode);
queries[i].v = splayTree.getPos(queries[i].vNode);
}
}
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
#ifdef Flower_On_Stone
freopen("input.txt", "r", stdin);
freopen("test.txt", "w", stdout);
#endif
cin >> numCake >> firstEat;
maxCake = numCake;
for (int i = 1; i <= numCake; i++) {
cin >> cake[i];
}
cin >> numQuery;
for (int i = 1; i <= numQuery; i++) {
cin >> queries[i].type;
if (queries[i].type == 'E') {
cin >> queries[i].pos >> queries[i].v;
} else {
cin >> queries[i].pos;
}
}
buildSplayTree();
buildQuery();
for (int i = 1; i <= numCake; i++) {
cake[i] = splayTree.getPos(initNode[i]);
}
smt.init(numCake, cake);
for (int i = 1; i <= numQuery; i++) {
if (queries[i].type == 'E') {
smt.update(queries[i].pos, queries[i].v);
cake[queries[i].pos] = queries[i].v;
} else {
if (queries[i].pos == firstEat) {
cout << 0 << '\n';
continue;
} else if (queries[i].pos < firstEat) {
int maxSegment = smt.get(queries[i].pos, firstEat - 1);
int low = firstEat, high = numCake;
while (low <= high) {
int mid = (low + high) / 2;
if (smt.get(firstEat + 1, mid) < maxSegment) {
low = mid + 1;
} else {
high = mid - 1;
}
}
cout << high - queries[i].pos << '\n';
} else {
int maxSegment = smt.get(firstEat + 1, queries[i].pos);
int low = 1, high = firstEat;
while (low <= high) {
int mid = (low + high) / 2;
if (smt.get(mid, firstEat - 1) < maxSegment) {
high = mid - 1;
} else {
low = mid + 1;
}
}
cout << queries[i].pos - low << '\n';
}
}
}
return 0;
}
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
6492 KB |
Output is correct |
2 |
Correct |
1 ms |
6488 KB |
Output is correct |
3 |
Correct |
1 ms |
6492 KB |
Output is correct |
4 |
Correct |
5 ms |
6780 KB |
Output is correct |
5 |
Correct |
16 ms |
7360 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
374 ms |
44928 KB |
Output is correct |
2 |
Correct |
189 ms |
45260 KB |
Output is correct |
3 |
Correct |
303 ms |
44980 KB |
Output is correct |
4 |
Correct |
160 ms |
45136 KB |
Output is correct |
5 |
Correct |
409 ms |
48152 KB |
Output is correct |
6 |
Correct |
323 ms |
48000 KB |
Output is correct |
7 |
Correct |
326 ms |
48236 KB |
Output is correct |
8 |
Correct |
171 ms |
48004 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
278 ms |
21556 KB |
Output is correct |
2 |
Correct |
157 ms |
21580 KB |
Output is correct |
3 |
Correct |
152 ms |
21472 KB |
Output is correct |
4 |
Correct |
1 ms |
6492 KB |
Output is correct |
5 |
Correct |
366 ms |
30244 KB |
Output is correct |
6 |
Correct |
443 ms |
30296 KB |
Output is correct |
7 |
Correct |
278 ms |
30172 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
58 ms |
10144 KB |
Output is correct |
2 |
Correct |
61 ms |
10104 KB |
Output is correct |
3 |
Correct |
153 ms |
17792 KB |
Output is correct |
4 |
Correct |
119 ms |
17792 KB |
Output is correct |
5 |
Correct |
140 ms |
16732 KB |
Output is correct |
6 |
Correct |
281 ms |
25252 KB |
Output is correct |
7 |
Correct |
210 ms |
18468 KB |
Output is correct |
8 |
Correct |
214 ms |
32428 KB |
Output is correct |
9 |
Correct |
1175 ms |
53404 KB |
Output is correct |
10 |
Correct |
457 ms |
33928 KB |
Output is correct |
11 |
Correct |
605 ms |
35492 KB |
Output is correct |
12 |
Correct |
1074 ms |
50816 KB |
Output is correct |
13 |
Correct |
1028 ms |
53540 KB |
Output is correct |