[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 ...
随机推荐
- 【习题 4-2 Uva201】Squares
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 注意那个星号的数量... 然后V x y的话,是从(y,x)向(y+1,x)连线. H x y才是从(x,y)向(x,y+1)连线 ...
- eclipse怎样开启/关闭代码提示功能
把以下红色框中的勾勾选上就是使用代码提示功能,不选就是关闭.
- 【SQLSERVER】MD5注意事项
sql中使用MD5加密是很常见的事情,但是不知道注意点的人还是会即便是拷贝网络上的写法也是会出现错误的. 举个例子简单说明: 由上图我们可以发现相同的字符串但是得到的MD5加密的字符却是不相同的,那么 ...
- Flex布局 Flexbox属性具体解释
原文:A Visual Guide to CSS3 Flexbox Properties Flex布局官方称为CSS Flexble Box布局模型是CSS3为了提高元素在容器中的对齐.方向.顺序,甚 ...
- AES 加密位: 128位,加密模式:CBC, 填充模式:Zeros
// AES 加密 public byte[] AESEncrypt(string text) { byte[] data = Encoding.Unicode.GetBytes(text); Sym ...
- Visio的安装教程
1.下载地址:https://msdn.itellyou.cn/ 2.输入关键字:Visio,选择想要下载的版本,展开详细信息,并复制 3.(我下载的13) ed2k://|file|cn_visio ...
- CodeForces 651C
Description Watchmen are in a danger and Doctor Manhattan together with his friend Daniel Dreiberg s ...
- nyoj--106--背包问题(贪心,水题)
背包问题 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 现在有很多物品(它们是可以分割的),我们知道它们每个物品的单位重量的价值v和重量w(1<=v,w<= ...
- HttpServletRequest对象小结
当客户端通过HTTP协议访问服务器时,请求所有信息都封装在HttpServletRequest对象中,可通过它获取到请求的所有信息,其常用方法如下: getRequestURL方法返回客户端发出请求时 ...
- sublime中BracketHighlighter 插件使用 (转)
sublime中BracketHighlighter 插件使用 1.打开package Control,选择install Package 2.输入BracketHighlighter,回车 3.这样 ...