博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ1500:[NOI2005]维修数列(Splay)
阅读量:7223 次
发布时间:2019-06-29

本文共 5941 字,大约阅读时间需要 19 分钟。

Description

请写一个程序,要求维护一个数列,支持以下 6 种操作:
请注意,格式栏 中的下划线‘ _ ’表示实际输入文件中的空格

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

9 8
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

-1
10
1
10

HINT

Solution

平衡树模板(呵

qtmd
注意插入后更新不能用splay函数……
因为可能插入的是0之类的然后splay就RE了
只能用两个update或者splay+特判

题目卡空间记得回收节点编号

Code

1 #include
2 #include
3 #include
4 #define N (500000+100) 5 using namespace std; 6 7 int Lmax[N],Rmax[N],Mmax[N],Sum[N],Cov[N],Rev[N]; 8 int n,m,pos,tot,Root,a[N]; 9 int stack[N],top,sz,k; 10 int Val[N],Size[N],Son[N][2],Father[N]; 11 char opt[21]; 12 13 int Get(int x) {
return Son[Father[x]][1]==x;} 14 void Clear(int x) {stack[++top]=x; Cov[x]=Rev[x]=Sum[x]=Mmax[x]=Lmax[x]=Rmax[x]=Father[x]=Son[x][0]=Son[x][1]=Size[x]=Val[x]=0;} 15 int Getid() {
if (!top) return ++sz; return stack[top--];} 16 17 void Update(int x) 18 { 19 Sum[x]=Sum[Son[x][0]]+Sum[Son[x][1]]+Val[x]; 20 Size[x]=Size[Son[x][0]]+Size[Son[x][1]]+1; 21 Mmax[x]=max(max(Mmax[Son[x][0]],Mmax[Son[x][1]]),Rmax[Son[x][0]]+Lmax[Son[x][1]]+Val[x]); 22 Lmax[x]=max(Lmax[Son[x][0]],Sum[Son[x][0]]+Lmax[Son[x][1]]+Val[x]); 23 Rmax[x]=max(Rmax[Son[x][1]],Sum[Son[x][1]]+Val[x]+Rmax[Son[x][0]]); 24 } 25 26 int Build(int l,int r,int fa) 27 { 28 if (l>r) return 0; 29 if (l==r) 30 { 31 int id=Getid(); 32 Val[id]=Sum[id]=Mmax[id]=a[l]; 33 Size[id]=1; 34 Father[id]=fa; 35 Lmax[id]=Rmax[id]=max(a[l],0); 36 return id; 37 } 38 int mid=(l+r)>>1; 39 int id=Getid(); 40 Son[id][0]=Build(l,mid-1,id); 41 Son[id][1]=Build(mid+1,r,id); 42 Father[id]=fa; 43 Val[id]=a[mid]; 44 Update(id); 45 return id; 46 } 47 48 void Pushdown(int x) 49 { 50 int l=Son[x][0],r=Son[x][1]; 51 if(Cov[x]) 52 { 53 Rev[x]=Cov[x]=0; 54 if(l)Cov[l]=1,Val[l]=Val[x],Sum[l]=Val[x]*Size[l]; 55 if(r)Cov[r]=1,Val[r]=Val[x],Sum[r]=Val[x]*Size[r]; 56 if(Val[x]>=0) 57 { 58 if(l)Lmax[l]=Rmax[l]=Mmax[l]=Sum[l]; 59 if(r)Lmax[r]=Rmax[r]=Mmax[r]=Sum[r]; 60 } 61 else 62 { 63 if(l)Lmax[l]=Rmax[l]=0,Mmax[l]=Val[x]; 64 if(r)Lmax[r]=Rmax[r]=0,Mmax[r]=Val[x]; 65 } 66 } 67 if(Rev[x]) 68 { 69 Rev[x]^=1;Rev[l]^=1;Rev[r]^=1; 70 swap(Lmax[l],Rmax[l]);swap(Lmax[r],Rmax[r]); 71 swap(Son[l][0],Son[l][1]);swap(Son[r][0],Son[r][1]); 72 } 73 } 74 75 void Rotate(int x) 76 { 77 int wh=Get(x); 78 int fa=Father[x],fafa=Father[fa]; 79 Father[fa]=x; Son[fa][wh]=Son[x][wh^1]; 80 if (Son[fa][wh]) Father[Son[fa][wh]]=fa; 81 Father[x]=fafa; Son[x][wh^1]=fa; 82 if (fafa) Son[fafa][Son[fafa][1]==fa]=x; 83 Update(fa); 84 Update(x); 85 } 86 87 void Push(int x){
if (x!=Root) Push(Father[x]); Pushdown(x);} 88 void Splay(int x,int tar) 89 { 90 Push(x); 91 for (int fa;(fa=Father[x])!=tar;Rotate(x)) 92 if (Father[fa]!=tar) 93 Rotate(Get(fa)==Get(x)?fa:x); 94 if (!tar) Root=x; 95 } 96 97 int Findx(int x) 98 { 99 int now=Root;100 while (1)101 {102 Pushdown(now);103 if (Size[Son[now][0]]>=x)104 now=Son[now][0];105 else106 {107 x-=Size[Son[now][0]];108 if (x==1)109 {110 Splay(now,0);111 return now;112 }113 x--;114 now=Son[now][1];115 }116 }117 }118 119 int Split(int x,int y)120 {121 int xx=Findx(x);122 int yy=Findx(y);123 Splay(xx,0); Splay(yy,xx);124 return Son[yy][0];125 }126 127 void Clear_up(int x)128 {129 if (Son[x][0]) Clear_up(Son[x][0]);130 if (Son[x][1]) Clear_up(Son[x][1]);131 Clear(x);132 }133 134 void INSERT(int pos,int tot)135 {136 Split(pos+1,pos+2);137 for (int i=1;i<=tot;++i)138 scanf("%d",&a[i]);139 int x=Build(1,tot,Son[Root][1]);140 Son[Son[Root][1]][0]=x;141 Update(Son[Root][1]); Update(Root);142 }143 144 void DELETE(int pos,int tot)145 {146 int x=Split(pos,pos+tot+1);147 Son[Father[x]][Get(x)]=0;148 Clear_up(x);149 Update(Son[Root][1]); Update(Root);150 }151 152 void MAKE_SAME(int pos,int tot,int k)153 {154 int x=Split(pos,pos+tot+1);155 Cov[x]=k;156 Val[x]=k; Cov[x]=1; Sum[x]=Size[x]*k;157 if(k>=0)Lmax[x]=Rmax[x]=Mmax[x]=Sum[x];158 else Lmax[x]=Rmax[x]=0,Mmax[x]=k;159 Update(Son[Root][1]); Update(Root);160 }161 162 void REVERSE(int pos,int tot)163 {164 int x=Split(pos,pos+tot+1);165 Rev[x]^=1;166 swap(Son[x][0],Son[x][1]);167 swap(Lmax[x],Rmax[x]);168 Update(Son[Root][1]); Update(Root);169 }170 171 void GET_SUM(int pos,int tot)172 {173 int x=Split(pos,pos+tot+1);174 printf("%d\n",Sum[x]);175 Update(Son[Root][1]); Update(Root);176 }177 178 int main()179 {180 scanf("%d%d",&n,&m);181 for (int i=1;i<=n;++i)182 scanf("%d",&a[i+1]);183 Mmax[0]=a[1]=a[n+2]=-0x3fffffff;184 Build(1,n+2,0);185 Root=1;186 while (m--)187 {188 scanf("%s",opt);189 if (opt[0]!='M' || opt[2]!='X') scanf("%d%d",&pos,&tot);190 if (opt[0]=='I') INSERT(pos,tot);191 if (opt[0]=='D') DELETE(pos,tot);192 if (opt[0]=='M')193 {194 if (opt[2]=='X') printf("%d\n",Mmax[Root]);195 else scanf("%d",&k),MAKE_SAME(pos,tot,k);196 }197 if (opt[0]=='R')REVERSE(pos,tot);198 if (opt[0]=='G')GET_SUM(pos,tot);199 }200 }

转载于:https://www.cnblogs.com/refun/p/8685557.html

你可能感兴趣的文章
Hibernate的批量处理-批量插入
查看>>
烂泥:Wing FTP Server与mysql数据库整合
查看>>
Apache HTTP Server搭建虚拟主机
查看>>
烂泥:查看服务器的BIOS是否开启CPU虚拟化
查看>>
[招聘季]--留些回忆给青葱岁月
查看>>
SANS:2017年网络威胁情报现状调研报告
查看>>
Ntop性能提升方案
查看>>
人民日报发声,区块链成“兵家必争之地”,或成“国家战略”
查看>>
Fcoin交易所的危险游戏!韭菜请远离!
查看>>
新浪微博商业化:步子要再大一些
查看>>
虚拟资源引流变现
查看>>
联想网御防火墙内网地址映射不能直接访问临时解决方法
查看>>
响应式设计(Response Web Design)实践
查看>>
在VS2008中计算代码度量值
查看>>
Simple tutorial to phys2d. version 0.0.2
查看>>
将log4j输出到rsyslog服务器
查看>>
javascript中时间戳日期转换[转]
查看>>
boost bind使用指南 - Make Progress Everyday! - 博客频道 - CSDN.NET
查看>>
第二部分:开发简要指南-第七章 与其他应用程序交互
查看>>
Javascript this 的一些学习总结
查看>>