_bzoj1500 [NOI2005]维修数列【真·Splay】
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1500
注意MAX-SUM的时候,不可以是空串。
#include <cstdio>
#include <algorithm> const int maxn = 500005; int n, m, top, a[maxn], posi, tot, cc;
char opr[15];
struct Node {
Node * ch[2];
Node * fa;
int key, sm, mxl, mxr, mxs, siz, c, mx;
char rev;
Node(void);
int getsm(void) {
return c == -666666? sm: c * siz;
}
int getmxl(void) {
if (c == -666666) {
return rev? mxr: mxl;
}
if (c > 0) {
return c * siz;
}
return 0;
}
int getmxr(void) {
if (c == -666666) {
return rev? mxl: mxr;
}
if (c > 0) {
return c * siz;
}
return 0;
}
int getmxs(void) {
if (c == -666666) {
return mxs;
}
if (c > 0) {
return c * siz;
}
return 0;
}
int getmx(void) {
return c == -666666? mx: c;
}
} *nil, *root, *tnode;
Node * stk[maxn]; Node::Node(void) {
ch[0] = ch[1] = fa = nil;
key = sm = mxl = mxr = mxs = siz = rev = 0;
mx = c = -666666;
}
inline void pushup(Node * x) {
x->siz = x->ch[0]->siz + x->ch[1]->siz + 1;
x->sm = x->ch[0]->getsm() + x->ch[1]->getsm() + x->key;
x->mxl = std::max(x->ch[0]->getmxl(), x->ch[0]->getsm() + x->key + x->ch[1]->getmxl());
x->mxr = std::max(x->ch[1]->getmxr(), x->ch[1]->getsm() + x->key + x->ch[0]->getmxr());
x->mxs = std::max(x->ch[0]->getmxs(), x->ch[1]->getmxs());
x->mxs = std::max(x->mxs, x->ch[0]->getmxr() + x->key + x->ch[1]->getmxl());
x->mx = std::max(x->ch[0]->getmx(), x->ch[1]->getmx());
x->mx = std::max(x->mx, x->key);
}
inline void pushdown(Node * x) {
if (x->c != -666666) {
x->ch[0]->c = x->ch[1]->c = x->c;
x->key = x->c;
x->sm = x->c * x->siz;
if (x->c > 0) {
x->mxl = x->mxr = x->mxs = x->sm;
}
else {
x->mxl = x->mxr = x->mxs = 0;
}
x->c = -666666;
}
if (x->rev) {
x->rev = 0;
x->ch[0]->rev ^= 1;
x->ch[1]->rev ^= 1;
std::swap(x->ch[0], x->ch[1]);
}
}
inline void rotate(Node* x) {
Node *y = x->fa;
if (y == y->fa->ch[0]) {
y->fa->ch[0] = x;
}
else {
y->fa->ch[1] = x;
}
x->fa = y->fa;
int dir = x == y->ch[1];
y->ch[dir] = x->ch[dir ^ 1];
x->ch[dir ^ 1]->fa = y;
x->ch[dir ^ 1] = y;
y->fa = x;
pushup(y);
pushup(x);
}
inline void splay(Node * x, Node * rt) {
Node * p;
char flag1, flag2;
top = 0;
for (Node * i = x; i != rt; i = i->fa) {
stk[top++] = i;
}
for (int i = top - 1; ~i; --i) {
pushdown(stk[i]);
}
while (x->fa != rt) {
p = x->fa;
if (p->fa == rt) {
rotate(x);
}
else {
flag1 = p == p->fa->ch[1];
flag2 = x == p->ch[1];
if (flag1 ^ flag2) {
rotate(x);
}
else {
rotate(p);
}
rotate(x);
}
}
if (rt == nil) {
root = x;
}
}
inline void modify(int pos1, int pos2) {
Node * x = root;
pushdown(x);
while (pos1 != x->ch[0]->siz + 1) {
if (pos1 <= x->ch[0]->siz) {
x = x->ch[0];
}
else {
pos1 -= x->ch[0]->siz + 1;
x = x->ch[1];
}
pushdown(x);
}
splay(x, nil);
x = root;
pushdown(x);
while (pos2 != x->ch[0]->siz + 1) {
if (pos2 <= x->ch[0]->siz) {
x = x->ch[0];
}
else {
pos2 -= x->ch[0]->siz + 1;
x = x->ch[1];
}
pushdown(x);
}
splay(x, root);
}
inline Node* ist(int left, int right) {
if (left > right) {
return nil;
}
Node * rt = new Node, *t;
int mid = (left + right) >> 1;
rt->key = a[mid];
t = ist(left, mid - 1);
t->fa = rt;
rt->ch[0] = t;
t = ist(mid + 1, right);
t->fa = rt;
rt->ch[1] = t;
pushup(rt);
return rt;
}
void clear(Node * x) {
if (x == nil) {
return;
}
clear(x->ch[0]);
clear(x->ch[1]);
delete x;
} int main(void) {
//freopen("in.txt", "r", stdin);
nil = new Node;
root = nil;
scanf("%d%d", &n, &m);
for (int i = 2; i <= n + 1; ++i) {
scanf("%d", a + i);
}
root = ist(1, n = n + 2);
while (m--) {
scanf("%s", opr);
if (opr[2] == 'S') { // INSERT
scanf("%d%d", &posi, &tot);
n += tot;
++posi;
modify(posi, posi + 1);
for (int i = 1; i <= tot; ++i) {
scanf("%d", a + i);
}
tnode = ist(1, tot);
tnode->fa = root->ch[1];
root->ch[1]->ch[0] = tnode;
pushup(root->ch[1]);
pushup(root);
}
else if (opr[2] == 'L') { // DELETE
scanf("%d%d", &posi, &tot);
n -= tot;
++posi;
modify(posi - 1, posi + tot);
clear(root->ch[1]->ch[0]);
root->ch[1]->ch[0] = nil;
pushup(root->ch[1]);
pushup(root);
}
else if (opr[2] == 'K') { // MAKE-SAME
scanf("%d%d%d", &posi, &tot, &cc);
++posi;
modify(posi - 1, posi + tot);
root->ch[1]->ch[0]->c = cc;
pushup(root->ch[1]);
pushup(root);
}
else if (opr[2] == 'V') { // REVERSE
scanf("%d%d", &posi, &tot);
++posi;
modify(posi - 1, posi + tot);
root->ch[1]->ch[0]->rev ^= 1;
pushup(root->ch[1]);
pushup(root);
}
else if (opr[2] == 'T') { // GET-SUM
scanf("%d%d", &posi, &tot);
++posi;
modify(posi - 1, posi + tot);
printf("%d\n", root->ch[1]->ch[0]->getsm());
}
else { // MAX-SUM
modify(1, n);
printf("%d\n", root->ch[1]->ch[0]->getmx() > 0? root->getmxs(): root->ch[1]->ch[0]->getmx());
}
}
return 0;
}
_bzoj1500 [NOI2005]维修数列【真·Splay】的更多相关文章
- 【BZOJ】1500: [NOI2005]维修数列(splay+变态题)
http://www.lydsy.com/JudgeOnline/problem.php?id=1500 模板不打熟你确定考场上调试得出来? 首先有非常多的坑点...我遇到的第一个就是,如何pushu ...
- NOI2005维修数列(splay)
题目描述: Description 请写一个程序,要求维护一个数列,支持以下 6 种操作: 请注意,格式栏 中的下划线‘ _ ’表示实际输入文件中的空格 Input 输入的第1 行包含两个数N 和M( ...
- bzoj 1500: [NOI2005]维修数列 splay
1500: [NOI2005]维修数列 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 6556 Solved: 1963[Submit][Status ...
- 【BZOJ1500】【NOI2005】维修数列(Splay)
[BZOJ1500][NOI2005]维修数列(Splay) 题面 不想再看见这种毒瘤题,自己去BZOJ看 题解 Splay良心模板题 真的很简单 我一言不发 #include<iostream ...
- [BZOJ1500][NOI2005]维修数列 解题报告 Splay
Portal Gun:[BZOJ1500][NOI2005]维修数列 有一段时间没写博客了,最近在刚数据结构......各种板子背得简直要起飞,题目也是一大堆做不完,这里就挑一道平衡树的题来写写好了 ...
- BZOJ 1500: [NOI2005]维修数列 (splay tree)
1500: [NOI2005]维修数列 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 4229 Solved: 1283[Submit][Status ...
- 【BZOJ1500】[NOI2005]维修数列 Splay
[BZOJ1500][NOI2005]维修数列 Description Input 输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目.第2行 ...
- [NOI2005] 维修数列
1500: [NOI2005]维修数列 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 8397 Solved: 2530 Description In ...
- [BZOJ1500][NOI2005]维修数列---解题报告
Portal Gun:[BZOJ1500][NOI2005]维修数列 有一段时间没写博客了,最近在刚数据结构......各种板子背得简直要起飞,题目也是一大堆做不完,这里就挑一道平衡树的题来写写好了 ...
随机推荐
- 多线程调用COM组件的体会(CoInitialize)
调用任何COM组件之前,你必须首先初始化COM套件环境,即调用CoInitialize或CoInitializeEx.COM套件环境在线程的生存周期内有效,线程退出前需要调用CoUninitializ ...
- 《从0到1》读书笔记第一章"未来的挑战"第1记:把握潮流风向
这几天刚到手当前炙手可热的来自PayPal创始人Peter Thiel的<Zero to One>.中文名<从0到1>,由高玉芳翻译.中信出版社出版.由于到货时刚好有事情在忙, ...
- RGB中的颜色的设置
用来表示一个 RGB 颜色值. 语法 RGB(red, green, blue) RGB 函数的语法含有以下这些命名参数: 部分 描述 red 必要参数:Variant (Integer).数值范围从 ...
- LoadRunner 比较字符串是否相等
int strcmp ( const char *string1, const char *string2 );大小写敏感.int stricmp ( const char *string1, con ...
- centos+nginx+php-fpm+php include fastcgi_params php页面能訪问但空白,被fastcgi_params与fastcgi.conf害慘了
今天在centos上折腾这块是发现老是訪问页面时,浏览器中提示是200 ok.且訪问html后缀却是正常出现内容. 可是訪问php后缀却返回空白页面,同一时候查看全部的log没有发现不论什么出错信息; ...
- IOS报错:Unexpected ‘@’ in program
IOS开发中出现此错误的原因: 1.宏定义重复. 我在OC与C++混编的时候,由于C++中使用到了interface,在工程中年将interface从定义为struct,当引用此接口时候出现Unexp ...
- 【iOS-Tips】-小贴士
[iOS-Tips]-小贴士 1:UIImage的2种加载方式: 方式一:有缓存(图片所占用的内存会一直停留在程序中) //name是图片的文件名 + (UIImage *)imageNamed:(N ...
- IIS老革命遇到的一些问题
今天部署一个网站到IIS,遇到了一些问题.老革命遇上新问题.前不久搞java,接触了一下tomcat,觉得真麻烦.而tomcat大概是java阵营中最简单的了吧.想不到,IIS7,友好的图形界面下,也 ...
- myeclipse提示:Syntax error on tokens, delete these tokens怎么解决
有中文字符或者符号,包括空格. 上次遇到一个问题,检查了一遍语法没错误, 后来发现是拷贝代码的时候有一部分中文空格没删除,就出现这个问题了. 一个个删除就OK了.
- 基于Servlet API 如何实现转向时不再地址栏中显示转向后的地址?
A:redirect() B:sendRedirect() C:forward() D:transform()