[bzoj1500][NOI2005 维修数列] (splay区间操作)
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
- - - -
- GET-SUM
- MAX-SUM
- INSERT -
- DELETE
- MAKE-SAME
- REVERSE
- GET-SUM
- MAX-SUM
Sample Output
- -
HINT
Solution
- #include<cstdio>
- #include<iostream>
- #define N 500010
- #define inf 0x3f3f3f3f
- #define mid ((x>>1)+(y>>1)+(x&y&1))
- using namespace std;
- inline int Rin(){
- int x=,c=getchar(),f=;
- for(;c<||c>;c=getchar())
- if(!(c^))f=-;
- for(;c>&&c<;c=getchar())
- x=(x<<)+(x<<)+c-;
- return x*f;
- }
- struct nt{
- nt*ch[],*p;
- bool rev;int cov;
- int size,sum,v,lmx,rmx,mmx;
- bool d(){return this==p->ch[];}
- void setc(nt*c,int d){
- ch[d]=c;
- c->p=this;
- }
- void revIt(){
- rev^=;
- swap(lmx,rmx);
- swap(ch[],ch[]);
- }
- void covIt(int co){
- cov=v=co;
- sum=co*size;
- co>?lmx=rmx=mmx=sum:
- lmx=rmx=mmx=co;
- }
- void pu(){
- size=+ch[]->size+ch[]->size;
- sum=v+ch[]->sum+ch[]->sum;
- lmx=max(ch[]->lmx,ch[]->sum+v+max(ch[]->lmx,));
- rmx=max(ch[]->rmx,ch[]->sum+v+max(ch[]->rmx,));
- mmx=max(max(ch[]->mmx,ch[]->mmx),max(ch[]->rmx,)+v+max(ch[]->lmx,));
- }
- void relax(){
- if(rev)
- ch[]->revIt(),
- ch[]->revIt();
- if(cov^inf)
- ch[]->covIt(cov),
- ch[]->covIt(cov);
- rev=;
- cov=inf;
- }
- };
- nt*null=new nt();
- nt*root=null;
- int n,a[N],m;
- char sign[];
- nt*newnode(nt*p,int v){
- nt*o=new nt();
- o->size=;
- o->v=o->sum=o->lmx=o->rmx=o->mmx=v;
- o->ch[]=o->ch[]=null;
- o->cov=inf;
- o->p=p;
- return o;
- }
- void rot(nt*&o){
- nt*p=o->p;
- p->relax();
- o->relax();
- bool d=o->d();
- p->p->setc(o,p->d());
- p->setc(o->ch[!d],d);
- o->setc(p,!d);
- p->pu();o->pu();
- if(p==root)root=o;
- }
- void splay(nt*o,nt*p){
- while(o->p!=p)
- if(o->p->p==p)
- rot(o);
- else
- o->d()^o->p->d()?(rot(o),rot(o)):(rot(o->p),rot(o));
- o->pu();
- }
- nt*build(int x,int y){
- if(x>y)return null;
- nt*o=newnode(o,a[mid]);
- o->setc(build(x,mid-),);
- o->setc(build(mid+,y),);
- o->pu();
- return o;
- }
- void del(nt*&o){
- if(o->ch[]!=null)del(o->ch[]);
- if(o->ch[]!=null)del(o->ch[]);
- delete o;
- }
- nt*kth(int k){
- for(nt*o=root;;){
- o->relax();
- if(k<=o->ch[]->size)
- o=o->ch[];
- else{
- k-=o->ch[]->size+;
- if(!k)return o;
- o=o->ch[];
- }
- }
- }
- int main(){
- n=Rin(),m=Rin();
- for(int i=;i<=n;i++)a[i]=Rin();
- root=build(,n+);
- root->p=null;
- int x,y,z;
- while(m--){
- scanf("%s",sign);
- switch(sign[]){
- case'S':
- x=Rin(),y=Rin();
- for(int i=;i<=y;i++)a[i]=Rin();
- splay(kth(x+),null);
- splay(kth(x+),root);
- root->ch[]->setc(build(,y),);
- root->ch[]->pu();
- root->pu();
- break;
- case'L':
- x=Rin(),y=Rin();
- splay(kth(x),null);
- splay(kth(x+y+),root);
- del(root->ch[]->ch[]);
- root->ch[]->ch[]=null;
- root->ch[]->pu();
- root->pu();
- break;
- case'K':
- x=Rin(),y=Rin(),z=Rin();
- splay(kth(x),null);
- splay(kth(x+y+),root);
- root->ch[]->ch[]->covIt(z);
- root->ch[]->pu();
- root->pu();
- break;
- case'T':
- x=Rin(),y=Rin();
- splay(kth(x),null);
- splay(kth(x+y+),root);
- printf("%d\n",root->ch[]->ch[]->sum);
- break;
- case'V':
- x=Rin(),y=Rin();
- splay(kth(x),null);
- splay(kth(x+y+),root);
- root->ch[]->ch[]->revIt();
- root->ch[]->pu();
- root->pu();
- break;
- case'X':
- splay(kth(),null);
- splay(kth(root->size),root);
- printf("%d\n",root->ch[]->ch[]->mmx);
- break;
- default:break;
- }
- }
- return ;
- }
[bzoj1500][NOI2005 维修数列] (splay区间操作)的更多相关文章
- BZOJ1500: [NOI2005]维修数列 [splay序列操作]【学习笔记】
以前写过这道题了,但我把以前的内容删掉了,因为现在感觉没法看 重写! 题意: 维护一个数列,支持插入一段数,删除一段数,修改一段数,翻转一段数,查询区间和,区间最大子序列 splay序列操作裸题 需要 ...
- P2042 [NOI2005]维护数列 && Splay区间操作(四)
到这里 \(A\) 了这题, \(Splay\) 就能算入好门了吧. 今天是个特殊的日子, \(NOI\) 出成绩, 大佬 \(Cu\) 不敢相信这一切这么快, 一下子机房就只剩我和 \(zrs\) ...
- BZOJ1500: [NOI2005]维修数列[splay ***]
1500: [NOI2005]维修数列 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 12278 Solved: 3880[Submit][Statu ...
- bzoj1500: [NOI2005]维修数列 (Splay+变态题)
Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 11353 Solved: 3553 [Submit][Status][Discuss] Descrip ...
- [bzoj1500][NOI2005]维修数列——splay
题目 题解 这道题可以说是数列问题的大BOSS,也算是这一周来学习splay等数据结构的一个总结. 我们一个一个地看这些操作. 对于操作1,我们首先建一棵子树,直接接上原树即可. 对于操作2,我们找到 ...
- BZOJ1500 [NOI2005]维修数列(Splay tree)
[Submit][Status][Discuss] Description 请写一个程序,要求维护一个数列,支持以下 6 种操作: 请注意,格式栏 中的下划线‘ _ ’表示实际输入文件中的空格 Inp ...
- [BZOJ1500][NOI2005]维修数列 解题报告 Splay
Portal Gun:[BZOJ1500][NOI2005]维修数列 有一段时间没写博客了,最近在刚数据结构......各种板子背得简直要起飞,题目也是一大堆做不完,这里就挑一道平衡树的题来写写好了 ...
- [BZOJ1500][NOI2005]维修数列---解题报告
Portal Gun:[BZOJ1500][NOI2005]维修数列 有一段时间没写博客了,最近在刚数据结构......各种板子背得简直要起飞,题目也是一大堆做不完,这里就挑一道平衡树的题来写写好了 ...
- 【BZOJ1500】[NOI2005]维修数列 Splay
[BZOJ1500][NOI2005]维修数列 Description Input 输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目.第2行 ...
随机推荐
- JSP-Runood:Eclipse JSP/Servlet 环境搭建
ylbtech-JSP-Runood:Eclipse JSP/Servlet 环境搭建 1.返回顶部 1. Eclipse JSP/Servlet 环境搭建 本文假定你已安装了 JDK 环境,如未安装 ...
- Java中的经典算法之冒泡排序
原理:比较两个相邻的元素,将值大的元素交换至右端. 思路:依次比较相邻的两个数,将小数放在前面,大数放在后面.即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后.然后比较第2个数和第3个数,将 ...
- hive 内部表与外部表的区别
hive 内部表: hive> create table soyo55(name STRING,addr STRING,money STRING) row format delimited fi ...
- 【Learning】多项式的一些东西
FFT 坑 NTT 将\(FFT\)中的单位复数根改成原根即可. 卡常版NTT模版 struct Mul { int Len; int wn[N], Lim; int rev[N]; inline v ...
- [Swift通天遁地]一、超级工具-(17)自定义的CVCalendar日历
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- CSS3常用知识点
CSS3常用知识点 1 css3选择器 1.1 属性选择器 /* E[attr~=val] 表示的一个单独的属性值 这个属性值是以空格分隔的*/ .attr2 a[class~="kawa& ...
- $割点割顶tarjan$
原题 #include <bits/stdc++.h> using namespace std; typedef long long LL; inline LL read () { LL ...
- jQuery——表单应用(4)
HTML: <!--复选框应用--> <!DOCTYPE html> <html> <head> <meta charset="UTF- ...
- 二分搜索poj106
Cable master Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 49944 Accepted: 10493 De ...
- 题解报告:poj 1321 棋盘问题(dfs)
Description 在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别.要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子 ...