_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]维修数列 有一段时间没写博客了,最近在刚数据结构......各种板子背得简直要起飞,题目也是一大堆做不完,这里就挑一道平衡树的题来写写好了 ...
随机推荐
- Linux上设置RAID 10
RAID 10(又叫RAID 1+0或镜像条带)阵列结合了RAID 0和RAID 1两者的功能特性,从而提供了高性能.容错的磁盘输入/输出操作.在RAID 0中,读取/写入操作跨多个驱动器并路执行:在 ...
- Spring之IOC篇章具体解释
专题一 IOC 1.接口以及面向接口编程 a.结构设计中,分清层次以及调用关系,每层仅仅向外(或者上层)提供一组功能接口,各层间仅依赖接口而非实现类这样做的优点是,接口实现的变动不影响各层间的调用 ...
- hdu 5087 Revenge of LIS II ( LIS ,第二长子序列)
链接:hdu 5087 题意:求第二大的最长升序子序列 分析:这里的第二大指的是,全部的递增子序列的长度(包含相等的), 从大到小排序后.排在第二的长度 cid=546" style=&qu ...
- IE将開始屏蔽旧版ActiveX控件
微软IE团队上周宣布将在IE中屏蔽旧版本号的ActiveX控件以加强IE的安全性.首先会被禁用的旧版本号ActiveX控件包括: J2SE 1.4, 低于update 43 的版本号 J2SE 5.0 ...
- 【Mongodb教程 第九课 】MongoDB 删除文档
remove() 方法 MongoDB的 remove() 方法用于从集合中删除文档.remove() 方法接受两个参数.第一个是删除criteria ,第二是justOne标志: deletion ...
- 【Mongodb教程 第一课 】 MongoDB下载安装
MongoDB是一个高性能,开源,无模式的文档型数据库,是当前NoSql数据库中比较热门的一种.它在许多场景下可用于替代传统的关系型数据库或键/值存储方式.Mongo使用C++开发.以window平台 ...
- LoadRunner系列之—-01 接口压力测试脚本
LoadRunner中一般用如下函数进行接口测试: <一>. http或soap协议下的get请求接口,样例如下: web_url("integrated_query.jsp&q ...
- Java SE之break和continue标签
文是学习网络上的文章时的总结,感谢大家无私的分享. Java没有提供goto功能,可是保留了gotokeyword. 在java中能够使用break标签和continue标签功能实现简版的goto功能 ...
- bean的scope属性
1.singleton (默认属性) Spring将Bean放入Spring IOC容器的缓存池中,并将Bean引用返回给调用者,spring IOC继续对这些Bean进行后续的生命管理.Bean ...
- V4L学习
http://blog.csdn.net/wangrunmin/article/details/7764768# http://blog.sina.com.cn/s/blog_a44175a90101 ...