[NOI2005]维护数列_Splay
真的毫无算法可言,就是比谁的码力强罢了...
Code:
#include<stack>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 500000 + 200;
const int inf = -1223;
int ch[maxn][2], f[maxn], numv[maxn], maxv[maxn], lmax[maxn], rmax[maxn], sumv[maxn], tag[maxn], lazy[maxn],siz[maxn];
int root, arr[maxn];
stack <int> S;
struct Operation
{
inline void init(){ for(int i = maxn - 10; i >= 1; --i) S.push(i); }
inline int new_node(){ int u = S.top(); S.pop(); return u; }
inline void erase(int x)
{
ch[x][0] = ch[x][1] = f[x] = 0;
maxv[x] = numv[x] = lmax[x] = rmax[x] = sumv[x] = tag[x] = siz[x] = 0;
lazy[x] = inf;
}
inline void trash(int u)
{
if(!u) return ;
S.push(u);
trash(ch[u][0]);
trash(ch[u][1]);
erase(u);
}
inline void pushup(int o)
{
int ls = ch[o][0], rs = ch[o][1];
maxv[o] = numv[o];
sumv[o] = sumv[ls] + sumv[rs] + numv[o];
siz[o] = siz[ls] + siz[rs] + 1;
int sums = numv[o];
if(ls) maxv[o] = max(maxv[o], maxv[ls]), sums += rmax[ls];
if(rs) maxv[o] = max(maxv[o], maxv[rs]), sums += lmax[rs];
maxv[o] = max(maxv[o], sums);
lmax[o] = max(lmax[ls], sumv[ls] + numv[o] + lmax[rs]);
rmax[o] = max(rmax[rs], sumv[rs] + numv[o] + rmax[ls]);
}
inline void maintain(int o)
{
maxv[o] = max(numv[o], sumv[o]);
lmax[o] = rmax[o] = max(0, sumv[o]);
}
inline void pushdown(int x)
{
int ls = ch[x][0], rs = ch[x][1];
if(lazy[x] != inf)
{
if(ls){ numv[ls] = lazy[ls] = lazy[x], sumv[ls] = siz[ls] * numv[ls]; maintain(ls); }
if(rs){ numv[rs] = lazy[rs] = lazy[x], sumv[rs] = siz[rs] * numv[rs]; maintain(rs); }
lazy[x] = inf;
}
if(tag[x])
{
swap(lmax[ls], rmax[ls]); swap(lmax[rs], rmax[rs]);
swap(ch[ls][0], ch[ls][1]); swap(ch[rs][0], ch[rs][1]);
if(ls) tag[ls] ^= 1;
if(rs) tag[rs] ^= 1;
tag[x] = 0;
}
}
void build(int l,int r,int fa,int &o)
{
if(l > r) return ;
int mid = (l + r) >> 1;
o = new_node();
f[o] = fa, numv[o] = arr[mid], lazy[o] = inf;
build(l, mid - 1, o, ch[o][0]);
build(mid + 1, r, o, ch[o][1]);
pushup(o);
}
}T;
inline int get(int x){ return ch[f[x]][1] == x;}
inline void rotate(int x)
{
int old = f[x], oldf = f[old], which = get(x);
ch[old][which] = ch[x][which ^ 1], f[ch[old][which]] = old;
ch[x][which ^ 1] = old, f[old] = x, f[x] = oldf;
if(oldf)
ch[oldf][ch[oldf][1] == old] = x;
T.pushup(old); T.pushup(x);
}
inline void splay(int x,int &tar)
{
int a = f[tar];
for(int fa; (fa = f[x]) != a; rotate(x))
if(f[fa] != a) rotate(get(x) == get(fa) ? fa : x);
tar = x;
}
inline int findx(int x, int top)
{
int cur = top;
while(1)
{
T.pushdown(cur);
int ls = ch[cur][0];
if(x == siz[ls] + 1) return cur;
if(x <= siz[ls]) cur = ch[cur][0];
else x -= siz[ls] + 1, cur = ch[cur][1];
}
return 0;
}
inline void split(int &a, int nums, int &b)
{
if(nums == 0)
{
b = a, a = 0; return ;
}
if(nums == siz[a])
{
b = 0; return ;
}
int u = findx(nums, a);
splay(u, a);
b = ch[a][1], f[ch[a][1]] = 0 , ch[a][1] = 0;
T.pushup(a);
}
inline void merge(int &a, int &b)
{
if(!a)
{
a = b; return ;
}
int u = findx(siz[a], a);
splay(u, a);
ch[a][1] = b, f[ch[a][1]] = a;
T.pushup(a);
}
inline void Insert()
{
int pos, tot;
scanf("%d%d",&pos,&tot);
for(int i = 1;i <= tot; ++i) scanf("%d",&arr[i]);
int a = 0, b = 0;
split(root, pos, a);
T.build(1, tot, 0, b);
merge(root, b);
merge(root, a);
}
inline void Delete()
{
int pos, tot;
scanf("%d%d",&pos,&tot);
int a , b;
split(root, pos - 1, a);
split(a, tot, b);
T.trash(a);
merge(root, b);
}
inline void Make_Same()
{
int pos, tot, c, a = 0, b = 0;
scanf("%d%d%d",&pos,&tot,&c);
split(root, pos - 1, a), split(a, tot, b);
sumv[a] = siz[a] * c, lazy[a] = c, numv[a] = c;
T.maintain(a);
merge(root, a), merge(root, b);
}
inline void Reverse()
{
int pos, tot, a = 0, b = 0;
scanf("%d%d",&pos,&tot);
split(root, pos - 1, a); split(a, tot, b);
tag[a] ^= 1;
swap(lmax[a], rmax[a]), swap(ch[a][0], ch[a][1]);
merge(root, a), merge(root, b);
}
inline void Get_sum()
{
int pos, tot, a = 0, b = 0;
scanf("%d%d",&pos,&tot);
split(root, pos - 1, a), split(a, tot, b);
printf("%d\n",sumv[a]);
merge(root, a), merge(root, b);
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
T.init();
for(int i = 1;i <= n; ++i) scanf("%d",&arr[i]);
T.build(1, n, 0, root);
for(int i = 1;i <= m; ++i)
{
char str[30];
scanf("%s",str);
if(str[0] == 'I') Insert();
if(str[0] == 'D') Delete();
if(str[2] == 'K') Make_Same();
if(str[0] == 'R') Reverse();
if(str[0] == 'G') Get_sum();
if(str[2] == 'X') printf("%d\n",maxv[root]);
}
return 0;
}
[NOI2005]维护数列_Splay的更多相关文章
- BZOJ_1500_[NOI2005]维修数列_splay
BZOJ_1500_[NOI2005]维修数列_splay 题意: 分析: 节点维护从左开始的最大连续子段和,从右开始的最大连续子段和,区间的最大连续子段和 插入:重新建一棵树,把pos旋到根,把po ...
- 数据结构(Splay平衡树):COGS 339. [NOI2005] 维护数列
339. [NOI2005] 维护数列 时间限制:3 s 内存限制:256 MB [问题描述] 请写一个程序,要求维护一个数列,支持以下 6 种操作:(请注意,格式栏 中的下划线‘ _ ’表示实际 ...
- [NOI2005] 维护数列
[NOI2005] 维护数列 题目 传送门 请写一个程序,要求维护一个数列,支持以下 6 种操作:(请注意,格式栏 中的下划线‘ _ ’表示实际输入文件中的空格) 操作编号 输入文件中的格式 说明 1 ...
- P2042 [NOI2005]维护数列 && Splay区间操作(四)
到这里 \(A\) 了这题, \(Splay\) 就能算入好门了吧. 今天是个特殊的日子, \(NOI\) 出成绩, 大佬 \(Cu\) 不敢相信这一切这么快, 一下子机房就只剩我和 \(zrs\) ...
- 洛谷 P2042 [NOI2005]维护数列-Splay(插入 删除 修改 翻转 求和 最大的子序列)
因为要讲座,随便写一下,等讲完有时间好好写一篇splay的博客. 先直接上题目然后贴代码,具体讲解都写代码里了. 参考的博客等的链接都贴代码里了,有空再好好写. P2042 [NOI2005]维护数列 ...
- P2042 [NOI2005]维护数列[splay或非旋treap·毒瘤题]
P2042 [NOI2005]维护数列 数列区间和,最大子列和(必须不为空),支持翻转.修改值.插入删除. 练码力的题,很毒瘤.个人因为太菜了,对splay极其生疏,犯了大量错误,在此记录,望以后一定 ...
- Luogu P2042 [NOI2005]维护数列(平衡树)
P2042 [NOI2005]维护数列 题意 题目描述 请写一个程序,要求维护一个数列,支持以下\(6\)种操作:(请注意,格式栏中的下划线'_'表示实际输入文件中的空格) 输入输出格式 输入格式: ...
- [NOI2005]维护数列(区间splay)
[NOI2005]维护数列(luogu) 打这玩意儿真是要了我的老命 Description 请写一个程序,要求维护一个数列,支持以下 6 种操作:(请注意,格式栏 中的下划线‘ _ ’表示实际输入文 ...
- [转载]无旋treap:从单点到区间(例题 BZOJ1500&NOI2005 维护数列 )
转自ZZH大佬,原文:http://www.cnblogs.com/LadyLex/p/7182631.html 1500: [NOI2005]维修数列 Time Limit: 10 Sec Mem ...
随机推荐
- ZOJ 2699 Police Cities
Police Cities Time Limit: 10 Seconds Memory Limit: 32768 KB Once upon the time there lived a ki ...
- java里面的队列
非阻塞无界队列 ConcurrentLinkedQueue public static void main(String[] args) throws InterruptedException { ...
- js setTimeout函数
最近在看JS DOM编程艺术,在第十章的动画里面有个setTimeout函数的例子中涉及了很多的引号,研究了好大一会才看明白,综合网上各个大神的解释和自己的理解,其原理是这样的: 首先看下程序源代码: ...
- 在TOMCAT上手工生成及部署WAR包
以前是用ECLIPSE或是其它IDE自动生成,不明了. 这次手写JAVA,先生成CALSS来部署, 之后用WAR包来部署.(查了资料,好像直接用JAR来部署TOMCAT的WEB项目,不得行) 就上次生 ...
- 在tomcat上全手工部署Servlet3.0
从头写java文件的方式,编译成CLASS文件,加强对SERVLET容器的理解. 稍后试试JAR和WAR包. 文件内容(跟以前用IDE的一样): HelloServlet.java: package ...
- javascript--闭包与this
理解javascript中的闭包与this http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html http: ...
- [bzoj1614][Usaco2007Jan]Telephone Lines 架设电话线_二分答案_最短路
Telephone Lines bzoj-1614 Usaco-2007Jan 题目大意:给你一个n个点m条边的带边权无向图,求最短路.可以选取k条边免费. 注释:$1\le n\le 10^3$,$ ...
- C#编程中,在页面上如何弹出确认删除对话框
对于页面完成一个操作后,弹出一个对话框提示是否“操作成功”.举例如下:Response.Write("<script>alert('删除成功!')</script>& ...
- Ruby对象、变量和常量
Ruby操作的数据主要有部分:对象.类.变量.常量. 对象 在Ruby中表示数据的基本单位称为对象,在Ruby中一切都是对象. 经常使用对象: 数值对象 2.3.14.-5等表示数字的对象,另外还有矩 ...
- structs实现三种action的方法
第一种:一般类,带有public String execute()方法. 另外一种:继承LoginActionInterface implements Action接口的类. 第三种:继承LoginA ...