# [NOI2005]维修数列

Description

Input

Output

Sample Input
9 8
2 -6 3 5 1 -5 -3 6 3
GET-SUM 5 4
MAX-SUM
INSERT 8 3 -5 7 2
DELETE 12 1
MAKE-SAME 3 3 2
REVERSE 3 6
GET-SUM 5 4
MAX-SUM
Sample Output
-1
10
1
10
Source
Splay

Solution :

Code :

#include <bits/stdc++.h>
using namespace std;

#define rep(i, l, r) for (int i = (l); i <= (r); i++)
#define per(i, r, l) for (int i = (r); i >= (l); i--)
#define REP(i, n) for (int i = 0; i < (n); i++)
#define PER(i, n) for (int i = (n)-1; i >= 0; i--)
#define stack _stack
const int INF = ~0U>>2;
const int N = 555555;

template<typename T> inline void read(T &x){
x = 0; T f = 1; char ch = getchar();
while (!isdigit(ch)) {if (ch == '-') f = -1; ch = getchar();}
while (isdigit(ch))  {x = x * 10 + ch - '0'; ch = getchar();}
x *= f;
}
template<typename T> inline void write(T x){
static T a[20]; int ptr = 0;
if (!x) { puts("0"); return; }
if (x < 0) { putchar('-'); x = -x; }
while (x) a[ptr++] = x % 10, x /= 10;
per(i, ptr-1, 0) putchar('0' + a[i]);
putchar('\n');
}

struct info{
int lmx, rmx, sum, mx, val, sz;
void mark_same(int t){
sum = t * sz; val = t; lmx = rmx = mx = max(sum, t);
}
void mark_rev() { swap(lmx, rmx); }
void set_one(int t) { sz = 1; mark_same(t); }
};
inline void merge_info(info &F, const info &L, const info &R){
F.sz = L.sz + R.sz + 1;
F.sum = L.sum + R.sum + F.val;
int LL = max(0, L.rmx), RR = max(0, R.lmx);
F.lmx = max(L.lmx, L.sum + F.val + RR);
F.rmx = max(R.rmx, R.sum + F.val + LL);
F.mx = max(LL + F.val + RR, max(L.mx, R.mx));
}
struct mark{
bool rev, is_same; int same;
void mark_same(int t){ same = t; is_same = 1; }
void mark_rev(){ rev ^= 1; }
void clear(){ is_same = rev = false; }
};
struct node{
node *p, *c[2]; info I; mark M;
bool d(){ return p->c[1] == this; }
void sc(node *_c, bool _d) {c[_d] = _c; _c->p = this;}
}*Null, *root;
inline void mark_same(node *t, int same){ if (t == Null) return;
t->M.mark_same(same); t->I.mark_same(same);
}
inline void mark_rev(node *t){ if (t == Null) return;
t->M.mark_rev(); t->I.mark_rev(); swap(t->c[0], t->c[1]);
}

node mem[N];
node *stack[N]; int top;
int n, m, A[N];
char opt[N];

inline void init_memory(){ REP(i, N) stack[i] = mem + i; top = N; }
inline node *new_node(){ return stack[--top]; }
inline node *new_node(int val){
node *ret = new_node();
ret->I.set_one(val);
ret->c[0] = ret->c[1] = ret->p = Null;
ret->M.clear();
return ret;
}
inline void delete_node(node *t) { stack[top++] = t; }
inline void init_null(){
Null = new_node(-INF);
Null->I.sz = Null->I.sum = 0;
Null->c[0] = Null->c[1] = Null->p = Null;
}
inline void sweep(node *t_root){
static node *q[N];
if (x->c[0] != Null) q[++tail] = x->c[0];
if (x->c[1] != Null) q[++tail] = x->c[1];
delete_node(x);
}
}

inline void push_down(node *t){ if (t == Null) return;
mark &m = t->M;
if (m.is_same){
mark_same(t->c[0], m.same); mark_same(t->c[1], m.same);
m.is_same = false;
}
if (m.rev){mark_rev(t->c[0]); mark_rev(t->c[1]); m.rev ^= 1;}
}
inline void push_up(node *t){ if (t == Null) return;
merge_info(t->I, t->c[0]->I, t->c[1]->I);
}
inline void rotate(node *t){
node *p = t->p; bool d = t->d(); push_down(p); push_down(t);
p->sc(t->c[!d], d);
if (p-p == Null) t->p = Null; else p->p->sc(t, p->d());
t->sc(p, !d); push_up(p);
if (p == root) root = t;
}
inline void splay(node *t, node *f){
for(push_down(t); t->p != f;){
if (t->p->p == f) rotate(t);
else t->d() == t->p->d() ?
(rotate(t->p), rotate(t)): (rotate(t), rotate(t));
}
push_up(t);
}
inline node *make_tree(int *l, int *r){
if (l >= r) return Null;
if (l + 1 == r) { return new_node(*l); }
int *mid = l+(r-l)/2;
node *t = new_node(*mid);
t->sc(make_tree(l, mid), 0); t->sc(make_tree(mid+1, r), 1);
push_up(t);
return t;
}
inline node *find(int k){
for(node *t = root; ;){push_down(t);
int cnt = t->c[0]->I.sz;
if (cnt == k) return t;
t = t->c[k>cnt];
if (k>cnt) k -= cnt+1;
}
}
node *&getseq(int l, int r){
node *L = find(l); splay(L, Null);
node *R = find(r); splay(R, root);
return root->c[1]->c[0];
}

inline void build(){
init_memory(); init_null(); root = new_node(-INF + 1);
node *End = new_node(-INF + 1);
root->sc(End, 1);
splay(End, Null);
}
inline void _insert(int tot, int pos){
node *t_root = make_tree(A, A+tot);
getseq(pos, pos+1);
root->c[1]->sc(t_root, 0);
splay(t_root, Null);
}
inline void _delete(int tot, int pos){
node *t_root = getseq(pos - 1, pos + tot);
t_root->p->sc(Null, 0);
splay(root->c[1], Null);
sweep(t_root);
}
inline void _reverse(int tot, int pos){
node *t_root = getseq(pos - 1, pos + tot);
mark_rev(t_root);
splay(t_root, Null);
}
inline void _modify(int tot, int pos, int val){
node *t_root = getseq(pos - 1, pos + tot);
mark_same(t_root, val);
splay(t_root, Null);
}
inline void _calc_sum(int tot, int pos){
node *t_root = getseq(pos - 1, pos + tot);
write(t_root->I.sum);
}
inline void _calc_max(){ write(root->I.mx); }

inline void solve(){
_insert(n, 0); int tot, pos, val;
while (m--){
scanf("%s", opt);
switch(opt[0]){
case 'M':
if (opt[2] == 'X') _calc_max();
else{
} OK
break;
}
}
}
int main(){
solve(); return 0;
}

• 本文已收录于以下专栏：

## bzoj1500 [NOI2005]维修数列解题报告

Bzoj 1500: [NOI2005]维修数列 解题报告 题目原文 Time Limit: 10 Sec  Memory Limit: 64 MB Submit: 10429  Solved: 3...
• 2016年02月17日 14:46
• 1159

## 【 bzoj 1500 】NOI2005 维修序列 - 平衡树乱搞 treap

• GEOTCBRL
• 2016年02月02日 23:31
• 1146

## [NOI2005]维修数列

[NOI2005]维修数列 中文题，题意不解释。。 平衡树模板，做法不解释。。就看你模板是否够硬了。。 先来发伸展树： #include #include #include using namespa...
• No__stop
• 2014年03月08日 10:43
• 1062

## 【平衡树维护序列】BZOJ1500(NOI2005)[维修数列]题解

BZOJ1500题解。
• zzkksunboy
• 2017年03月31日 09:19
• 383

## bzoj1500【NOI2005】维修数列

Splay维护区间......旋转吧！！Splay！！
• AaronGZK
• 2015年11月28日 22:55
• 799

## BZOJ 1500 【NOI2005 D1T2】 维修数列 Splay

• YihAN_Z
• 2016年12月10日 19:23
• 286

## 【BZOJ1500】[NOI2005]维修数列 Splay

Splay终极模板题…… 很清楚，像线段树一样wei
• eolv99
• 2014年10月04日 15:56
• 551

## [BZOJ1500][NOI2005]维修数列（Splay）

ATP并不能理解为什么有人会不喜欢指针→_→
• FromATP
• 2016年11月09日 22:00
• 384

## 【BZOJ 1500】 [NOI2005]维修数列

• Regina8023
• 2014年11月26日 23:04
• 933

## [bzoj1500][NOI2005]维修数列

• gddswlz
• 2013年06月14日 11:08
• 678

举报原因： 您举报文章：[BZOJ1500][NOI2005]维修数列 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)