bzoj千题计划221:bzoj1500: [NOI2005]维修数列(fhq treap)
http://www.lydsy.com/JudgeOnline/problem.php?id=1500
1、覆盖标记用INF表示无覆盖标记,要求可能用0覆盖
2、代表空节点的0号节点和首尾的两个虚拟节点,所有有关取max的信息全部设为负无穷,但注意不要无穷相加爆掉int
3、空间,用一个队列回收已删除的节点的编号
4、建树的时候采用的笛卡尔树的构造方式,但并没有比错误的忽略优先级的build快多少
5、手写的max快
inline
int
& max(
int
&x,
int
&y) {
return
x > y ? x : y; }
#define max(x, y) ((x) > (y) ? (x) : (y))
#include<queue>
#include<cstdio>
#include<cstdlib>
#include<iostream>
//#include<algorithm> using namespace std; #define N 500005 #define INF 1e9 int tot,root; int pri[N],val[N];
int sum[N],mxr[N],mxl[N],mx[N];
int ch[N][],siz[N];
bool rev[N];
int tag[N]; int pos,cnt,w; int a[N]; queue<int>trash; int st[N],top; void read(int &x)
{
x=; int f=; char c=getchar();
while(!isdigit(c)) { if(c=='-') f=-; c=getchar();}
while(isdigit(c)) { x=x*+c-''; c=getchar();}
x*=f;
} inline int& max(int &x, int &y) { return x > y ? x : y; } void update(int x)
{
int l=ch[x][],r=ch[x][];
siz[x]=siz[l]+siz[r]+;
sum[x]=sum[l]+sum[r]+val[x];
mx[x]=max(mx[l],mx[r]);
mx[x]=max(mx[x],mxr[l]+val[x]);
mx[x]=max(mx[x],mxl[r]+val[x]);
mx[x]=max(mx[x],mxr[l]+mxl[r]+val[x]);
mx[x]=max(mx[x],val[x]);
mxr[x]=max(mxr[r],sum[r]+mxr[l]+val[x]);
mxr[x]=max(mxr[x],sum[r]+val[x]);
mxl[x]=max(mxl[l],sum[l]+mxl[r]+val[x]);
mxl[x]=max(mxl[x],sum[l]+val[x]);
} void down(int x)
{
if(rev[x])
{
int l=ch[x][],r=ch[x][];
if(l)
{
swap(ch[l][],ch[l][]);
swap(mxl[l],mxr[l]);
rev[l]^=;
}
if(r)
{
swap(ch[r][],ch[r][]);
swap(mxl[r],mxr[r]);
rev[r]^=;
}
rev[x]^=;
}
if(tag[x]!=INF)
{
int l=ch[x][],r=ch[x][];
if(l)
{
val[l]=tag[x];
sum[l]=mxl[l]=mxr[l]=mx[l]=siz[l]*tag[x];
tag[l]=tag[x];
}
if(r)
{
val[r]=tag[x];
sum[r]=mxl[r]=mxr[r]=mx[r]=siz[r]*tag[x];
tag[r]=tag[x];
}
tag[x]=INF;
}
} int newnode(int v)
{
int now;
if(!trash.empty()) now=trash.front(),trash.pop();
else now=++tot;
siz[now]=;
val[now]=v;
pri[now]=rand();
tag[now]=INF;
sum[now]=mx[now]=mxl[now]=mxr[now]=v;
rev[now]=false;
ch[now][]=ch[now][]=;
return now;
} int build(int l,int r)
{
int now,last; top=;
for(int i=l;i<=r;++i)
{
now=newnode(a[i]);
last=;
while(top && pri[st[top]]>pri[now])
{
update(st[top]);
last=st[top--];
}
if(top) ch[st[top]][]=now;
ch[now][]=last; st[++top]=now;
}
while(top) update(st[top--]);
return st[];
} void split(int now,int p,int &x,int &y)
{
if(!now) x=y=;
else
{
down(now);
if(p<=siz[ch[now][]])
{
y=now;
split(ch[now][],p,x,ch[now][]);
}
else
{
x=now;
split(ch[now][],p-siz[ch[now][]]-,ch[now][],y);
}
update(now);
}
} int merge(int x,int y)
{
if(x) down(x);
if(y) down(y);
if(!x || !y) return x+y;
if(pri[x]<pri[y])
{
ch[x][]=merge(ch[x][],y);
update(x);
return x;
}
else
{
ch[y][]=merge(x,ch[y][]);
update(y);
return y;
}
} int find(int k)
{
int now=root;
while()
{
down(now);
if(k<=siz[ch[now][]]) now=ch[now][];
else
{
k-=siz[ch[now][]];
if(k==) return now;
k--;
now=ch[now][];
}
}
} void insert()
{
read(pos); read(cnt);
pos++;
for(int i=;i<=cnt;++i) read(a[i]);
int rt=build(,cnt);
int a,b;
split(root,pos,a,b);
int e=merge(a,rt);
root=merge(e,b);
} void del(int x)
{
if(!x) return;
trash.push(x);
del(ch[x][]);
del(ch[x][]);
} void solve(int ty)
{
read(pos); read(cnt);
pos++;
int a,b;
split(root,pos+cnt-,a,b);
int c,d;
split(a,pos-,c,d);
if(ty==)
{
del(d);
root=merge(c,b);
return;
}
if(ty==)
{
read(w);
tag[d]=w;
val[d]=w;
sum[d]=mxl[d]=mxr[d]=mx[d]=siz[d]*w;
}
else if(ty==)
{
rev[d]^=;
swap(ch[d][],ch[d][]);
swap(mxl[d],mxr[d]);
}
else if(ty==) printf("%d\n",sum[d]);
root=merge(merge(c,d),b);
} int main()
{
mx[]=mxl[]=mxr[]=-7e8;
int n,m;
read(n); read(m);
for(int i=;i<=n+;++i) read(a[i]);
a[]=a[n+]=-7e8;
root=build(,n+);
char s[];
while(m--)
{
scanf("%s",s);
if(s[]=='I') insert();
else if(s[]=='D') solve();
else if(s[]=='K') solve();
else if(s[]=='R') solve();
else if(s[]=='G') solve();
else printf("%d\n",mx[root]);
}
}
1500: [NOI2005]维修数列
Time Limit: 10 Sec Memory Limit: 64 MB
Submit: 15972 Solved: 5312
[Submit][Status][Discuss]
Description
Input
输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目。
第2行包含N个数字,描述初始时的数列。
以下M行,每行一条命令,格式参见问题描述中的表格。
任何时刻数列中最多含有500 000个数,数列中任何一个数字均在[-1 000, 1 000]内。
插入的数字总数不超过4 000 000个,输入文件大小不超过20MBytes。
Output
对于输入数据中的GET-SUM和MAX-SUM操作,向输出文件依次打印结果,每个答案(数字)占一行。
Sample Input
2 -6 3 5 1 -5 -3 6 3
GET-SUM 5 4
MAX-SUM
INSERT 8 3 -5 7 2
DELETE 12 1
MAKE-SAME 3 3 2
REVERSE 3 6
GET-SUM 5 4
MAX-SUM
Sample Output
10
1
10
HINT
bzoj千题计划221:bzoj1500: [NOI2005]维修数列(fhq treap)的更多相关文章
- BZOJ 1500 [NOI2005]维修数列 FHQ Treap
终于A了这题...这题还是很好...但是我太菜...重构了三遍qwq FHQ Treap大法好!qwq...~~ Ins:直接拿输入造一棵树,把原来的树split成[1,pos],[pos+1,n], ...
- bzoj千题计划293:bzoj3142: [Hnoi2013]数列
http://www.lydsy.com/JudgeOnline/problem.php?id=3142 如果已知数列的差分数列a[1]~a[k-1] 那么这种差分方式对答案的贡献为 N-Σ a[i] ...
- [BZOJ1500][NOI2005]维修数列---解题报告
Portal Gun:[BZOJ1500][NOI2005]维修数列 有一段时间没写博客了,最近在刚数据结构......各种板子背得简直要起飞,题目也是一大堆做不完,这里就挑一道平衡树的题来写写好了 ...
- [BZOJ1500][NOI2005]维修数列 解题报告 Splay
Portal Gun:[BZOJ1500][NOI2005]维修数列 有一段时间没写博客了,最近在刚数据结构......各种板子背得简直要起飞,题目也是一大堆做不完,这里就挑一道平衡树的题来写写好了 ...
- bzoj千题计划300:bzoj4823: [Cqoi2017]老C的方块
http://www.lydsy.com/JudgeOnline/problem.php?id=4823 讨厌的形状就是四联通图 且左右各连一个方块 那么破坏所有满足条件的四联通就好了 按上图方式染色 ...
- [bzoj1500][NOI2005]维修数列_非旋转Treap
维修数列 bzoj-1500 NOI-2005 题目大意:给定n个数,m个操作,支持:在指定位置插入一段数:删除一个数:区间修改:区间翻转.查询:区间和:全局最大子序列. 注释:$1\le n_{ma ...
- splay模板三合一 luogu2042 [NOI2005]维护数列/bzoj1500 [NOI2005]维修数列 | poj3580 SuperMemo | luogu3391 【模板】文艺平衡树(Splay)
先是维修数列 题解看这里,但是我写的跑得很慢 #include <iostream> #include <cstdio> using namespace std; int n, ...
- bzoj千题计划216:bzoj1499: [NOI2005]瑰丽华尔兹
http://www.lydsy.com/JudgeOnline/problem.php?id=1499 预处理从每个位置向每个方向最多能走几步 dp[k][i][j] 第k个时间段后,钢琴到位置(i ...
- bzoj千题计划196:bzoj4826: [Hnoi2017]影魔
http://www.lydsy.com/JudgeOnline/problem.php?id=4826 吐槽一下bzoj这道题的排版是真丑... 我还是粘洛谷的题面吧... 提供p1的攻击力:i,j ...
随机推荐
- REST-framework快速构建API--权限
我们在访问资源时,有些资源保密程度较高,需要特殊的人员才能访问.比如,获取公司的每日收入流水的API接口,只能CEO才能查看. 这时,我们就需要将资源设定权限了. REST-framework实现如下 ...
- eclipse中怎么找项目部署的路径和找编译后的class路径
1.快捷键 ctrl+shift+R,会默认显示你的源文件.java的路径,如果没有.class的话,点击右上角的三角,选中 Show Derived Resource; 2.打开出现下图 3.按下 ...
- 爱普生L313彩色打印相片
操作环境: windows 和MAC 一.普通打印(默认选项) 1.爱普生L313 普通默认打印为快速不清晰打印. 2.以上打印效果出来图片比较快速出图,但是清晰度不够 二.照片打印设置 1.照片设置 ...
- C++ string 类详解
字符串是存储在内存的连续字节中的一系列字符.C++ 处理字符串的方式有两种,一种来自 C 语言,常被称为 C-风格字符串,另一种是基于 string 类库的字符串处理方式.C 风格字符串的处理可以参考 ...
- Linux_02
1.vim编辑器 vim操作命令 --在命令模式下进行 pageup 往上翻页 pagedown 往下翻页 H 移动到屏幕首行 gg 移动光标到文档的首行 前面加数字n表示移动到n行内容 G 移动到文 ...
- 科普贴 | 数字钱包MetaMask安装使用详解,活用MetaMask轻松驾驭以太坊
MetaMask 是一款浏览器插件钱包,不需下载安装客户端,只需添加至浏览器扩展程序即可使用,非常方便.它是很多支持 ETH 参投的 ICO 项目推荐使用的钱包之一. 2018年初最火的一个币,应该就 ...
- 第三周:构造一个简单的LINUX系统MENUOS
吕松鸿 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.Linux内 ...
- 为什么HashMap不是线程安全的
电面突然被问到这个问题,之前看到过,但是印象不深,导致自己没有答出来,现在总结一下. HashMap的内部存储结构 transient Node<K,V>[] table; static ...
- ping出现dup问题
华为交换机收到mac地址漂移告警: Dec 24 2018 16:48:22+08:00 HW5320 %%01SECE/4/UCSUPPRESSRESUME(l) [66]:MAC address ...
- 11th 回忆整个学期——告学弟学妹
告诉后来的学弟学妹,不要因为艰难而却步,坚持下去才知道,山的对面是什么.很多东西或许一开始看起来是无用,甚至无意义的,但是努力去做,你才知道价值所在.不要等一切结束了,才懂得自己错过了什么.