_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]维修数列 有一段时间没写博客了,最近在刚数据结构......各种板子背得简直要起飞,题目也是一大堆做不完,这里就挑一道平衡树的题来写写好了 ...
随机推荐
- Meteor在手机上运行
在本章中,我们将学习如何在Android设备上运行你的应用程序.最近Meteor刚刚添加此功能适用于Windows操作系统,所以我们需要更新 Meteor 应用到 1.3测试版. 注 在写的时候本教程 ...
- Real-Time Compressive Tracking 论文笔记
总体思想 1 利用符合压缩感知RIP条件的随机感知矩阵对多尺度图像进行降维 2 然后对降维的特征採用简单的朴素贝叶斯进行分类 算法主要流程 1 在t帧的时候,我们採样得到若干张目标(正样本)和背景(负 ...
- php 文件压缩zip扩展
<?php function addFileToZip($path, $zip) { $handler = opendir($path); //打开当前文件夹由$path指定. while (( ...
- web编程非常实用的在线工具大全
目前,不管是前端开发人员还是个人站长,经常需要一些代码处理类的工具,比如:代码对比.代码格式化.图标制作等.有时就是一时急用可电脑上又没有安装相关的软件,这里为大家收集了一些我们经常会用到的在线工具. ...
- 2016/2/25 1, margin auto 垂直方向测试 无效 2,margin重叠 3,哪些是块状哪些是内联 4,display:block inline 导航栏把内联转块状最常见+ 扩展
1.利用margin auto完成首页居中,并自行研究,竖直方向用margin auto,是什么效果#container{width:1002px;margin: 0px auto;} 竖直方向 ...
- 调参侠的末日? Auto-Keras 自动搜索深度学习模型的网络架构和超参数
Auto-Keras 是一个开源的自动机器学习库.Auto-Keras 的终极目标是允许所有领域的只需要很少的数据科学或者机器学习背景的专家都可以很容易的使用深度学习.Auto-Keras 提供了一系 ...
- 移动端和PC端有什么区别
1.PC考虑的是浏览器的兼容性,而移动端开发考虑的更多的是手机兼容性,因为目前不管是android手机还是ios手机,一般浏览器使用的都是webkit内核,所以说做移动端开发,更多考虑的应该是手机分辨 ...
- XML解析(DOM)
001 public class DOM_Parser { 002 003 public static void main(String[] args) { 004 try ...
- AppCompatActivity、ActionBarActivity、FragmentActivity和Activity的区别
package com.chy.myapplication; import android.support.v7.app.AppCompatActivity; import android.os.Bu ...
- BZOJ3669(NOI2014):魔法森林 (LCT维护最小生成树)
为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号为1..N,边标号为1..M.初始时小E同学在号节点1,隐士则住在号节点N ...