#include <cstdio>
#include <queue>
#include <cstring>
using std::queue;
const int N = 100010;
struct node
{
node *c[2],*fa;
int val;
int sz;
int belong;
void setc(int d,node *s) {
c[d] = s;
s->fa = this;
}
bool d() {
return fa->c[1]==this;
}
void up(){
sz = c[0]->sz + c[1]->sz + 1;
}
void clear(node *null) {
sz = 1;
c[0] = c[1] = fa = null;
}
}NODE[N],*null=NODE;
node* ID[N];
int top;
struct Tree
{
node* root;
void init(int v) {
node* x = &NODE[++top];
x->belong = top;
x->val = v;
x->clear(null);
root = x;
}
void rot(node* x,int f) {
node* y = x->fa;
y->setc(!f,x->c[f]);
x->fa = y->fa;
if(y->fa!=null) y->fa->c[y->d()] = x;
x->setc(f,y);
y->up();
}
void splay(node *x,node *goal) {
while(x->fa!=goal) {
if(x->fa->fa == goal) rot(x,!x->d());
else {
bool f = x->fa->d();
x->d() == f ? rot(x->fa,!f): rot(x,f);
rot(x,!f);
}
}
x->up();
if(goal == null) root = x;
}
void RTO(int k,node *goal) {
node *x = root;
while(x->c[0]->sz+1 != k) {
if(x->c[0]->sz+1 > k) x = x->c[0];
else {
k -= x->c[0]->sz + 1;
x = x->c[1];
}
}
splay(x,goal);
}
void delRoot() {
node* t = root;
if(t->c[1]!=null) {
root = t->c[1];
RTO(1,null);
root->setc(0,t->c[0]);
// root->c[0] = t->c[0];
// if(root->c[0]!=null) root->c[0]->fa = root;
} else root = root->c[0];
root->fa = null;
if(root!=null) root->up();
}
void change(node* x,int v){
splay(x,null);
delRoot();
x->val = v;
x->clear(null);
insert(root,x);
}
void insert(node* &x,node *y,node* fa=null) {// 如何减少对父亲指针的赋值
if(x == null) {
x = y;
y->fa = fa;
return ;
}
if(x->val >= y->val) insert(x->c[0],y,x);
else insert(x->c[1],y,x);
x->up();
}
int find(node *x,int k) {
if(x->c[0]->sz + 1 == k) return x->val;
else if(x->c[0]->sz + 1 > k) return find(x->c[0],k);
else return find(x->c[1],k-x->c[0]->sz-1);
}
void debug(node *x) {
printf("%d lc:%d rc:%d\n",x->val,x->c[0]->val,x->c[1]->val);
if(x->c[0]!=null) debug(x->c[0]);
if(x->c[1]!=null) debug(x->c[1]);
}
}spt[N];
板二:
#include <iostream>
#include <cstdio>
#include <string.h>
#include <string>
#include <algorithm>
using namespace std;
const int maxn = 1000000 + 10;
const int inf = 1000000000;
struct Node
{
int val, d;
int sum, siz;
int max, mls, mrs;
Node * par, * ch[2];
bool rev, sm;
};
Node * root, * null;
Node nod[maxn];
Node * Ind[maxn];
int tot;
int number[maxn], nc;
struct SplayTree
{
Node * NewNode(int val, Node * par)
{
Node * x = Ind[tot++];
x->val = x->sum = x->max = x->mls = x->mrs = val;
x->siz = 1;
x->par = par;
x->rev = x->sm = false;
if (x->ch[0] != null) Ind[--tot] = x->ch[0];
if (x->ch[1] != null) Ind[--tot] = x->ch[1];
x->ch[0] = x->ch[1] = null;
return x;
};
void Modify(Node * x, int d)
{
if (x == null) return;
x->val = x->d = d;
x->sm = true;
x->sum = x->siz * d;
x->mls = x->mrs = x->max = max(x->sum, d);
x->rev = false;
};
void Reverse(Node * x)
{
if (x == null) return;
x->rev ^= true;
swap(x->mls, x->mrs);
swap(x->ch[0], x->ch[1]);
}
void PushDown(Node * x)
{
if (x == null) return;
if (x->sm) {
Modify(x->ch[0], x->d);
Modify(x->ch[1], x->d);
x->sm = false;
}
if (x->rev) {
Reverse(x->ch[0]);
Reverse(x->ch[1]);
x->rev = false;
}
}
void PushUp(Node * x)
{
if (x == null) return;
x->siz = x->ch[0]->siz + x->ch[1]->siz + 1;
x->sum = x->ch[0]->sum + x->ch[1]->sum + x->val;
x->mls = max(x->ch[0]->mls, x->ch[0]->sum + x->val + max(0, x->ch[1]->mls));
x->mrs = max(x->ch[1]->mrs, x->ch[1]->sum + x->val + max(0, x->ch[0]->mrs));
x->max = max(x->ch[0]->max, x->ch[1]->max);
x->max = max(x->max, max(x->ch[0]->mrs, 0) + x->val + max(x->ch[1]->mls, 0));
return;
}
void Rotate(Node * x, int c)
{
Node * y = x->par;
PushDown(y);
PushDown(x);
y->ch[!c] = x->ch[c];
if (x->ch[c] != null) x->ch[c]->par = y;
x->par = y->par;
if (y->par != null) {
if (y->par->ch[0] == y) y->par->ch[0] = x;
else y->par->ch[1] = x;
}
x->ch[c] = y;
y->par = x;
PushUp(y);
if (y == root) root = x;
}
void Splay(Node * x, Node * f)
{
Node * y, * z;
for (PushDown(x); x->par != f; ) {
y = x->par, z = y->par;
if (z == f) {
if (y->ch[0] == x) Rotate(x, 1);
else Rotate(x, 0);
} else {
if (z->ch[0] == y) {
if (y->ch[0] == x) Rotate(y, 1), Rotate(x, 1);
else Rotate(x, 0), Rotate(x, 1);
} else {
if (y->ch[0] == x) Rotate(x, 1), Rotate(x, 0);
else Rotate(y, 0), Rotate(x, 0);
}
}
}
PushUp(x);
}
void Select(int k, Node * f)
{
Node * cur = root;
int temp;
while (1) {
PushDown(cur);
temp = cur->ch[0]->siz;
if (k == temp) break;
if (k < temp) cur = cur->ch[0];
else {
k -= (temp+1);
cur = cur->ch[1];
}
}
Splay(cur, f);
}
Node * Build(int L, int R, Node * par)
{
if (L > R) return null;
int mid = (L + R) / 2;
Node * x = NewNode(number[mid], par);
x->ch[0] = Build(L, mid - 1, x);
x->ch[1] = Build(mid + 1, R, x);
PushUp(x);
return x;
}
void Insert(int pos, int L, int R)
{
Select(pos, null);
Select(pos+1, root);
root->ch[1]->ch[0] = Build(L, R, root->ch[1]);
PushUp(root->ch[1]);
Splay(root->ch[1]->ch[0], null);
}
Node * Delete(int L, int R)
{
Node * ret;
Select(L - 1, null);
Select(R + 1, root);
ret = root->ch[1]->ch[0];
root->ch[1]->ch[0] = null;
PushUp(root->ch[1]);
Splay(root->ch[1], null);
return ret;
}
void Init()
{
null = &nod[0];
null->siz = null->sum = 0;
null->val = null->mls = null->mrs = null->max = -inf;
tot = 1;
for (int i = 0; i != maxn; i++) {
Ind[i] = &nod[i];
nod[i].ch[0] = nod[i].ch[1] = null;
}
}
void Modify(int L, int R, int d)
{
Select(L-1, null);
Select(R+1, root);
Modify(root->ch[1]->ch[0], d);
Splay(root->ch[1]->ch[0], null);
}
void Reverse(int L, int R)
{
Select(L-1, null);
Select(R+1, root);
Reverse(root->ch[1]->ch[0]);
Splay(root->ch[1]->ch[0], null);
}
int Sum(int L, int R)
{
Select(L-1, null);
Select(R+1, root);
return root->ch[1]->ch[0]->sum;
}
void Print()
{
Select(1, null);
printf("%d", root->val);
for (int i = 2; i <= root->siz - 2; i++) {
Select(i, null);
printf(" %d", root->val);
}
printf("\n");
}
} spt;
int n, m, x, y, D, T, len, P;
char op[30];
Node * temp;
int main()
{
//freopen("sequence.in", "r", stdin);
//freopen("sequence.out", "w", stdout);
char op[20];
int Q, p, cc;
Node * Left, * Right;
while (scanf("%d%d", &n, &Q)!=EOF) {
spt.Init();
for (int i = 1; i <= n; i++) scanf("%d", number + i);
root = Left = spt.NewNode(-inf, null);
Right = spt.NewNode(-inf, Left);
Left->sum = Right->sum = 0;
Left->ch[1] = Right;
Right->ch[0] = spt.Build(1, n, Right);
spt.PushUp(Right);
spt.PushUp(Left);
//spt.PushUp(root);
//spt.Print();
while (Q--) {
scanf("%s", op);
if (op[0] == 'M' && op[2] == 'X') printf("%d\n", root->max);
else {
scanf("%d%d", &p, &nc);
if (op[0] == 'I') {
for (int i = 1; i <= nc; i++) scanf("%d", number + i);
spt.Insert(p, 1, nc);
} else
if (op[0] == 'D') {
Ind[--tot] = spt.Delete(p, p + nc - 1);
} else
if (op[0] == 'R') {
spt.Reverse(p, p + nc - 1);
} else
if (op[0] == 'M') {
scanf("%d", &cc);
spt.Modify(p, p + nc - 1, cc);
} else
if (op[0] == 'G') {
printf("%d\n", spt.Sum(p, p + nc - 1));
}
}
//spt.Print();
}
}
return 0;
}
白书模版:
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<stdlib.h>
using namespace std;
#define N 20005
struct Treap{
Treap *ch[2];
int r; //数字越大,优先级越高
int v; //值
int size; //子树的节点数
Treap(int v):v(v) { ch[0]=ch[1]=NULL; r=rand(); size=1;}
bool operator < (const Treap& rhs) const{
return r < rhs.r;
}
int cmp(int x) const{
if(x == v)return -1;
return x < v ? 0 : 1;
}
void maintain(){ //以该点为根的子树节点数(包括自己)
size = 1;
if(ch[0] != NULL) size += ch[0]->size;
if(ch[1] != NULL) size += ch[1]->size;
}
};
Treap* root[N];
//d=0代表左旋,d=1代表右旋
void rotate(Treap* &o, int d){
Treap* k = o->ch[d^1]; o->ch[d^1] = k->ch[d]; k->ch[d] = o;
o->maintain(); k->maintain(); o = k;
}
//在以o为根的子树中插入键值x,修改o
void insert(Treap* &o, int x){
if(o == NULL) o = new Treap(x);
else {
int d = (x < o->v ? 0 : 1); //不要用cmp函数,因为可能会有相同的节点
insert(o->ch[d], x);
if(o->ch[d] > o) rotate(o, d^1);
}
o->maintain();
}
//删除键值为x的节点
void remove(Treap* &o, int x){
int d = o->cmp(x);
if(d == -1){
Treap* u = o;
if(o->ch[0] != NULL && o->ch[1] != NULL){
int d2 = (o->ch[0] > o->ch[1] ? 1: 0);
rotate(o, d2); remove(o->ch[d2], x);
}
else {
if(o->ch[0] == NULL) o = o->ch[1]; else o = o->ch[0];;
delete u;
}
}
else remove(o->ch[d], x);
if(o != NULL) o->maintain();
}
//第k大的值
int kth(Treap* o, int k){
if(o == NULL || k<=0 || k> o->size) return 0;
int s = (o->ch[1] == NULL ? 0 : o->ch[1]->size);
if( k == s+1) return o->v;
else if(k <= s) return kth(o->ch[1], k);
else return kth(o->ch[0], k - s - 1);
}
void mergeto(Treap* &src, Treap* &dest){
if(src->ch[0] != NULL) mergeto(src->ch[0], dest);
if(src->ch[1] != NULL) mergeto(src->ch[1], dest);
insert(dest, src->v);
delete src;
src = NULL;
}
void removetree(Treap* &x){
if(x->ch[0] != NULL) removetree(x->ch[0]);
if(x->ch[1] != NULL) removetree(x->ch[1]);
delete x;
x = NULL;
}
void splay(Treap* &o, int k){
int d = o->cmp(k);
if(d == 1) k -= o->ch[0]->size + 1;
if(d != 1) {
Treap * p = o->ch[d];
int d2 = p->cmp(k);
int k2 = (d2 == 0 ? k : k- p->ch[0]->size + 1);
if(d2 != 1) {
splay(p->ch[d2], k2);
if(d == d2) rotate(o, d^1); else rotate(o->ch[d], d);
}
rotate(o, d^1);
}
}
//合并left和right。假定left的所有元素比right小。注意right可以是NULL,但left不可以
Treap* merge(Treap* left, Treap* right){
splay(left, left->size);
left->ch[1] = right;
left->maintain();
return left;
}
//把o的前k小节点放在left里,其他的放在right里。l<=k<= o->size。 当k=o->size 时,right=NULL
void split(Treap* o, int k, Treap* &left, Treap* &right){
splay(o, k);
left = o;
right = o->ch[1];
o->ch[1] = NULL;
left->maintain();
}