#include <iostream>
#include <cstdlib>
#include <climits>
using namespace std;
typedef struct node {
int key, val, num, lazy;
long totalVal;
struct node *left, *right, *father;
}Node;
Node* createNode(int key, int val) {
Node *node = (Node*)malloc(sizeof(Node));
node->key = key;
node->val = val;
node->num = 1;
node->totalVal = val;
node->lazy = 0;
node->left = NULL;
node->right = NULL;
node->father = NULL;
return node;
}
void update(Node *x) {
//here must initialize
x->num = 1;
x->totalVal = x->val;
if (x->left) {
x->num += x->left->num;
x->totalVal += x->left->totalVal;
}
if (x->right) {
x->num += x->right->num;
x->totalVal += x->right->totalVal;
}
}
void marking(Node *x, int data) {
x->lazy += data;
x->totalVal += x->num * data;
x->val += data;
}
void send(Node *x) {
if (x->left)
marking(x->left, x->lazy);
if (x->right)
marking(x->right, x->lazy);
x->lazy = 0;
update(x);
}
void left_rotate(Node *x) {
Node *p = x->father;
send(p);
send(x);
x->father = p->father;
if (p->father) {
if (p->father->left == p)
p->father->left = x;
else
p->father->right = x;
}
p->right = x->left;
if (x->left)
x->left->father = p;
x->left = p;
p->father = x;
update(p);
update(x);
}
void right_rotate(Node *x) {
Node *p = x->father;
send(p);
send(x);
x->father = p->father;
if (p->father) {
if (p->father->left == p)
p->father->left = x;
else
p->father->right = x;
}
p->left = x->right;
if (x->right)
x->right->father = p;
x->right = p;
p->father = x;
update(p);
update(x);
}
//y must be ancestor of x, make x son of y
void splay(Node *x, Node *y) {
while (x->father != y) {
Node *p = x->father;
if (p->father == y) {
if (p->left == x)
right_rotate(x);
else
left_rotate(x);
}
else {
Node *g = p->father;
if (g->left == p) {
if (p->left == x) {
right_rotate(p);
right_rotate(x);
}
else {
left_rotate(x);
right_rotate(x);
}
}
else {
if (p->right == x) {
left_rotate(p);
left_rotate(x);
}
else {
right_rotate(x);
left_rotate(x);
}
}
}
}
}
Node* bst_insert(Node *root, int key, int val) {
if (!root)
return createNode(key, val);
if (root->key == key)
return root;
send(root);
if (root->key < key) {
root->right = bst_insert(root->right, key, val);
root->right->father = root;
}
else {
root->left = bst_insert(root->left, key, val);
root->left->father = root;
}
update(root);
return root;
}
Node* bst_find(Node *root, int key) {
if (!root)
return NULL;
if (root->key == key)
return root;
if (root->key < key)
return bst_find(root->right, key);
else
return bst_find(root->left, key);
}
Node* insert(Node *root, int key, int val) {
root = bst_insert(root, key, val);
Node *temp = bst_find(root, key);
splay(temp, NULL);
return temp;
}
Node* findPrev(Node *root) {
Node *node = root->left;
while (node->right)
node = node->right;
return node;
}
Node* findNext(Node *root) {
Node *node = root->right;
while (node->left)
node = node->left;
return node;
}
Node* deleteN(Node *root) {
Node *prev = findPrev(root);
Node *next = findNext(root);
splay(prev, NULL);
splay(next, prev);
next->left = NULL;
return prev;
}
Node* findPrev(Node *root, int key) {
Node *temp = bst_find(root, key);
if (temp) {
splay(temp, NULL);
temp = findPrev(temp);
splay(temp, NULL);
return temp;
}
else {
return deleteN(insert(root, key, 0));
}
}
Node* findNext(Node *root, int key) {
Node *temp = bst_find(root, key);
if (temp) {
splay(temp, NULL);
temp = findNext(temp);
splay(temp, NULL);
return temp;
}
else {
return deleteN(insert(root, key, 0))->right;
}
}
Node* query(Node *root, int a, int b) {
Node *prev = findPrev(root, a);
Node *next = findNext(prev, b);
splay(prev, NULL);
splay(next, prev);
return prev;
}
Node* manage(Node *root, int a, int b, int d) {
Node *prev = findPrev(root, a);
Node *next = findNext(prev, b);
splay(prev, NULL);
splay(next, prev);
marking(next->left, d);
root = next->left;
splay(root, NULL);
return root;
}
Node* deleteN(Node *root, int a, int b) {
root = insert(root, a, 0);
Node *prev = findPrev(root);
root = insert(root, b, 0);
Node *next = findNext(root);
splay(prev, NULL);
splay(next, prev);
next->left = NULL;
return prev;
}
int main()
{
int n, a, b, d;
char c;
Node *root = NULL;
root = insert(insert(root, INT_MAX, 0), INT_MIN, 0);
cin >> n;
for (int i = 0; i < n; i++) {
cin >> c;
switch (c) {
case 'I':
cin >> a >> b;
root = insert(root, a, b);
break;
case 'Q':
cin >> a >> b;
root = query(root, a, b);
cout << root->right->left->totalVal << endl;
break;
case 'M':
cin >> a >> b >> d;
root = manage(root, a, b, d);
break;
case 'D':
cin >> a >> b;
root = deleteN(root, a, b);
break;
default:
break;
}
}
return 0;
}
splay伸展树
最新推荐文章于 2022-10-28 20:32:48 发布