维修数列代码及简易题解

总体方案:将左右端点分别转到根和根的右儿子,将目标序列挤到以根的右儿子的左儿子为根的子树中,然后进行一系列骚操作即可

建树:用类似线段树的方法建树,递归即可,注意加两个边界点

插入:读入这些数,用建树函数建出一颗子树,接到根的右儿子的左儿子处

删除:递归删除即可

修改:在根的右儿子的左儿子处打懒标记,像线段树一样

求和:输出根的右儿子的左儿子的sum

求最大子序列:利用线段树合并的思想即可。

此题细节极多,具体见代码

鄙人为了能过,进行了大量的特判,再加上鄙人不想写内存回收,用了作死指针,码风奇丑无比,众巨佬们勿喷。

  1 #include
  2 struct node
  3 {
  4     int val,sum,set,laz,siz,lm,rm,maxv,setv,vod;
  5     node *fa,*son[2];
  6     node()
  7     {
  8         fa=NULL;
  9         son[0]=son[1]=NULL;
 10         val=sum=set=laz=siz=setv=vod=0;
 11         lm=rm=maxv=-(1<<30);
 12     }
 13 };
 14 node *root,*fail;
 15 int n,m,v[500100],n0,p0,p1,c;
 16 char op[50];
 17 int max(int a,int b){return a>b?a:b;}
 18 void pushup(node *nc)
 19 {
 20     nc->siz=nc->son[0]->siz+nc->son[1]->siz+1;
 21     nc->sum=nc->son[0]->sum+nc->son[1]->sum+nc->val;
 22     if((!nc->son[0]->siz&&!nc->son[1]->siz)||(nc->son[0]->vod&&nc->son[1]->vod&&nc->son[0]->siz==1&&nc->son[1]->siz==1)||(!nc->son[0]->siz&&nc->son[1]->vod&&nc->son[1]->siz==1)||(!nc->son[1]->siz&&nc->son[0]->vod&&nc->son[0]->siz==1))
 23     {
 24         nc->lm=nc->val;
 25         nc->rm=nc->val;
 26         nc->maxv=nc->val;
 27         return;
 28     }
 29     if(!nc->son[0]->siz||(nc->son[0]->vod&&nc->son[0]->siz==1))
 30     {
 31         if(!nc->vod)
 32         {
 33             nc->maxv=max(nc->val+nc->son[1]->lm,max(nc->son[1]->maxv,nc->val));
 34             nc->lm=max(nc->val+nc->son[1]->lm,nc->val);
 35         }
 36         else
 37         {
 38             nc->lm=nc->son[1]->lm;
 39             nc->maxv=max(nc->val+nc->son[1]->lm,nc->son[1]->maxv);
 40         }
 41         nc->rm=max(nc->son[1]->rm,nc->val+nc->son[1]->sum);
 42         return;
 43     }
 44     if(!nc->son[1]->siz||(nc->son[1]->vod&&nc->son[1]->siz==1))
 45     {
 46         nc->lm=max(nc->val+nc->son[0]->sum,nc->son[0]->lm);
 47         if(!nc->vod)
 48         {
 49             nc->rm=max(nc->son[0]->rm+nc->val,nc->val);
 50             nc->maxv=max(nc->val+nc->son[0]->rm,max(nc->son[0]->maxv,nc->val));
 51         }
 52         else
 53         {
 54             nc->rm=nc->son[0]->rm;
 55             nc->maxv=max(nc->val+nc->son[0]->rm,nc->son[0]->maxv);
 56         }
 57         return;
 58     }
 59     nc->lm=max(nc->son[0]->lm,nc->son[0]->sum+max(nc->son[1]->lm,0)+nc->val);
 60     nc->rm=max(nc->son[1]->rm,nc->son[1]->sum+max(nc->son[0]->rm,0)+nc->val);
 61     nc->maxv=max(max(max(nc->son[0]->maxv,nc->son[1]->maxv),nc->val),max(nc->son[0]->rm+nc->val+nc->son[1]->lm,max(nc->val,max(nc->val+nc->son[1]->lm,nc->son[0]->rm+nc->val))));
 62 }
 63 void plaz(node* nc)
 64 {
 65     node* tmp=nc->son[0];
 66     nc->son[0]=nc->son[1];
 67     nc->son[1]=tmp;
 68     int ti=nc->lm;
 69     nc->lm=nc->rm;
 70     nc->rm=ti;
 71 }
 72 void pushdown(node *nc)
 73 {
 74     if(nc->set)
 75     {
 76         if(nc->son[0]->siz)
 77         {
 78             nc->son[0]->set=1;
 79             nc->son[0]->setv=nc->setv;
 80             nc->son[0]->sum=nc->son[0]->siz*nc->son[0]->setv;
 81             nc->son[0]->val=nc->setv;
 82         }
 83         if(nc->son[1]->siz)
 84         {
 85             nc->son[1]->set=1;
 86             nc->son[1]->setv=nc->setv;
 87             nc->son[1]->sum=nc->son[1]->siz*nc->son[1]->setv;
 88             nc->son[1]->val=nc->setv;
 89         }
 90         if(nc->setv>0)
 91         {
 92             if(nc->son[1]->siz)
 93             {
 94                 nc->son[1]->lm=nc->son[1]->sum;
 95                 nc->son[1]->rm=nc->son[1]->sum;
 96                 nc->son[1]->maxv=nc->son[1]->sum;
 97             }
 98             if(nc->son[0]->siz)
 99             {
100                 nc->son[0]->lm=nc->son[0]->sum;
101                 nc->son[0]->rm=nc->son[0]->sum;
102                 nc->son[0]->maxv=nc->son[0]->sum;
103             }
104         }
105         else
106         {
107             if(nc->son[1]->siz)
108             {
109                 nc->son[1]->lm=nc->setv;
110                 nc->son[1]->rm=nc->setv;
111                 nc->son[1]->maxv=nc->setv;
112             }
113             if(nc->son[0]->siz)
114             {
115                 nc->son[0]->lm=nc->setv;
116                 nc->son[0]->rm=nc->setv;
117                 nc->son[0]->maxv=nc->setv;
118             }
119         }
120         nc->setv=0;
121         nc->set=0;
122     }
123     if(nc->laz)
124     {
125         nc->son[0]->laz^=1;
126         nc->son[1]->laz^=1;
127         nc->laz=0;
128         plaz(nc->son[0]);
129         plaz(nc->son[1]);
130     }
131 }
132 void rot(node* x,node* &k)
133 {
134     node* y=x->fa;
135     node* z=y->fa;
136     int lx=y->son[1]==x;
137     int rx=lx^1;
138     if(y==k)
139     {
140         k=x;
141     }
142     else
143     {
144         z->son[z->son[1]==y]=x;
145     }
146     x->fa=z;
147     y->fa=x;
148     x->son[rx]->fa=y;
149     y->son[lx]=x->son[rx];
150     x->son[rx]=y;
151     pushup(y);
152     pushup(x);
153 }
154 void splay(node* x,node* &k)
155 {
156     while(x!=k)
157     {
158         node* y=x->fa;
159         node* z=y->fa;
160         if(y!=k)
161         {
162             if((y->son[0]==x)^(z->son[0]==y))
163             {
164                 rot(x,k);
165             }
166             else
167             {
168                 rot(y,k);
169             }
170         }
171         rot(x,k);
172     }
173 }
174 node* find(node* x,int rk)
175 {
176     pushdown(x);
177     if(rkson[0]->siz)
178     {
179         return find(x->son[0],rk);
180     }
181     else
182     {
183         if(rk==x->son[0]->siz+1)
184         {
185             return x;
186         }
187         else
188         {
189             return find(x->son[1],rk-1-x->son[0]->siz);
190         }
191     }
192 }
193 int fri;
194 void build(int l,int r,node* nc,int x)
195 {
196     if(r<l)
197     {
198         nc->son[x]=fail;
199         return;
200     }
201     if(x==3)
202     {
203         int mid=(l+r)/2;
204         build(l,mid-1,nc,0);
205         build(mid+1,r,nc,1);
206         nc->val=v[mid];
207         pushup(nc);
208         return;
209     }
210     if(l==r)
211     {
212         node* tmp=new node();
213         tmp->fa=nc;
214         tmp->siz=1;
215         tmp->val=v[l];
216         tmp->sum=v[l];
217         nc->son[x]=tmp;
218         tmp->son[0]=fail;
219         tmp->son[1]=fail;
220         tmp->lm=v[l];
221         tmp->rm=v[l];
222         tmp->maxv=v[l];
223         if(fri&&(l==1||l==n+2))
224         {
225             tmp->vod=1;
226         }
227         return;
228     }
229     int mid=(l+r)/2;
230     node* tmp=new node();
231     tmp->fa=nc;
232     tmp->val=v[mid];
233     nc->son[x]=tmp;
234     tmp->lm=v[mid];
235     tmp->rm=v[mid];
236     tmp->maxv=v[mid];
237     build(l,mid-1,tmp,0);
238     build(mid+1,r,tmp,1);
239     if(fri&&(mid==1||mid==n+2))
240     {
241         tmp->vod=1;
242     }
243     pushup(tmp);
244 }
245 void del(node* x)
246 {
247     if(x->son[0]->siz)
248     del(x->son[0]);
249     if(x->son[1]->siz)
250     del(x->son[1]);
251     delete x;
252 }
253 int main()
254 {
255     scanf("%d%d",&n,&m);
256     for(int i=2;i1;i++)
257     {
258         scanf("%d",&v[i]);
259     }
260     root=new node();
261     fail=new node();
262     fail->son[0]=fail;
263     fail->son[1]=fail;
264     fail->lm=0;
265     fail->rm=0;
266     fail->maxv=0;
267     fri=1;
268     build(1,n+2,root,3);
269     fri=0;
270     root->fa=root;
271     for(int i=1;i)
272     {
273         scanf("%s",op);
274         if(op[0]=='I')
275         {
276             scanf("%d%d",&p0,&n0);
277             node* x=find(root,p0+1);
278             node* y=find(root,p0+2);
279             splay(x,root);
280             splay(y,root->son[1]);
281             for(int j=1;j)
282             {
283                 scanf("%d",&v[j]);
284             }
285             node* rt=new node();
286             build(1,n0,rt,3);
287             rt->fa=root->son[1];
288             root->son[1]->son[0]=rt;
289             pushup(root->son[1]);
290             pushup(root);
291             n+=n0;
292         }
293         if(op[0]=='D')
294         {
295             scanf("%d%d",&p0,&p1);
296             node* x=find(root,p0);
297             node* y=find(root,p0+p1+1);
298             splay(x,root);
299             splay(y,root->son[1]);
300             n-=root->son[1]->son[0]->siz;
301             del(root->son[1]->son[0]);
302             root->son[1]->son[0]=fail;
303             pushup(root->son[1]);
304             pushup(root);
305         }
306         if(op[0]=='M'&&op[2]=='K')
307         {
308             scanf("%d%d%d",&p0,&p1,&c);
309             node* x=find(root,p0);
310             node* y=find(root,p1+p0+1);
311             splay(x,root);
312             splay(y,root->son[1]);
313             root->son[1]->son[0]->set=1;
314             root->son[1]->son[0]->setv=c;
315             root->son[1]->son[0]->sum=root->son[1]->son[0]->setv*root->son[1]->son[0]->siz;
316             root->son[1]->son[0]->val=root->son[1]->son[0]->setv;
317             if(root->son[1]->son[0]->setv>0)
318             {
319                 root->son[1]->son[0]->lm=root->son[1]->son[0]->sum;
320                 root->son[1]->son[0]->rm=root->son[1]->son[0]->sum;
321                 root->son[1]->son[0]->maxv=root->son[1]->son[0]->sum;
322             }
323             else
324             {
325                 root->son[1]->son[0]->lm=root->son[1]->son[0]->setv;
326                 root->son[1]->son[0]->rm=root->son[1]->son[0]->setv;
327                 root->son[1]->son[0]->maxv=root->son[1]->son[0]->setv;
328             }
329             pushup(root->son[1]);
330             pushup(root);
331         }
332         if(op[0]=='R')
333         {
334             scanf("%d%d",&p0,&p1);
335             node* x=find(root,p0);
336             node* y=find(root,p1+p0+1);
337             splay(x,root);
338             splay(y,root->son[1]);
339             root->son[1]->son[0]->laz^=1;
340             node* tmp=root->son[1]->son[0]->son[0];
341             root->son[1]->son[0]->son[0]=root->son[1]->son[0]->son[1];
342             root->son[1]->son[0]->son[1]=tmp;
343             int tt=root->son[1]->son[0]->lm;
344             root->son[1]->son[0]->lm=root->son[1]->son[0]->rm;
345             root->son[1]->son[0]->rm=tt;
346             pushup(root->son[1]);
347             pushup(root);
348         }
349         if(op[0]=='G')
350         {
351             scanf("%d%d",&p0,&p1);
352             node* x=find(root,p0);
353             node* y=find(root,p1+p0+1);
354             splay(x,root);
355             splay(y,root->son[1]);
356             printf("%d\n",root->son[1]->son[0]->sum);
357         }
358         if(op[0]=='M'&&op[2]=='X')
359         {
360             printf("%d\n",root->maxv);
361         }
362     }
363     del(root);
364     delete fail;
365     return 0;
366 }

Original: https://www.cnblogs.com/Grharris/p/10740944.html
Author: Grharris
Title: 维修数列代码及简易题解

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/578002/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 【学习笔记】week01

    1、按系列罗列Linux 的发行版,并描述不同发行版之间的联系与区别 (1) Slackware : l SUSE Linux 软件包齐全 (2) Debian : l ubunt…

    Linux 2023年5月27日
    068
  • n的阶乘前100项。Table of n! for n = 1..100

    n的阶乘前100项 {1,2,6,24,120,720,5040,40320,362880,3628800,39916800,479001600,6227020800,871782…

    Linux 2023年6月6日
    072
  • Redis缓存查询时报字段无法识别问题-SerializationException: Could not read JSON: Unrecognized xxx

    报错信息: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exce…

    Linux 2023年6月14日
    088
  • 每周一个linux命令(tar)

    基础环境 tar命令介绍 tar命令是linux非常使用频率非常高的一个命令,比如:离线软件包的解压缩、将一个目录打包备份、将一个压缩包解压到一个指定的目录。tar命令主要用来将一…

    Linux 2023年6月8日
    087
  • Docker ->(个人学习记录笔记)

    @ Docker基本使用 核心概念 docker常用命令 镜像操作 修改镜像源 容器操作 普通用户运行docker Docker基本使用 Docker是一个开源的应用容器引擎;是一…

    Linux 2023年5月27日
    0113
  • Docker 环境 Nacos2 MySQL8

    本文介绍 docker 环境下安装并单机运行 Nacos2,使用 docker 环境下的 MySQL 8 存储数据。 1 拉取镜像 1.1 创建目录 在硬盘上创建 nacos 的有…

    Linux 2023年6月7日
    088
  • BKT的胡测题解:第一套第三题base

    博客园 :当前访问的博文已被密码保护 请输入阅读密码: Original: https://www.cnblogs.com/Grharris/p/11550809.htmlAuth…

    Linux 2023年6月6日
    086
  • php uniapp 支付宝app支付,前后端实战源码

    uniapp端,前端代码 app.php端代码 Original: https://www.cnblogs.com/xiaofengzheng/p/16457966.htmlAut…

    Linux 2023年6月7日
    075
  • MIT6.828——Lab1 partA(麻省理工操作系统课程实验)

    Lab1 基本部分 在实验给出的文档中,已经详说明了早期PC的内存布局,并且运行了 bootloader。详细地解释了,上电后BIOS所做的工作,因此这部分不再赘述。需要注意的是 …

    Linux 2023年5月27日
    0157
  • redis开启远程访问

    redis默认只允许本地访问,要使redis可以远程访问可以修改redis.conf 打开redis.conf文件在 NETWORK部分有说明 By default, if no …

    Linux 2023年5月28日
    0146
  • Linux常用命令总结

    Linux常用命令总结 关机 & 重启&注销 常用命令 作用 shutdown -h now 即刻关机 shutdown -h 5 5分钟后关机 shutdown …

    Linux 2023年6月7日
    096
  • podman

    podman Podman 是一个无守护程序、开源的 Linux 原生工具,旨在使用开放容器计划 (OCI) 容器和容器映像轻松查找、运行、构建、共享和部署应用程序。Podman …

    Linux 2023年6月7日
    060
  • mit6.824 笔记 一

    分布式是复杂的系统再考虑分布式系统前应该尽可能尝试其他方法。 人们使用大量的相互协作的计算机驱动力是: 人们需要获得更高的计算性能。可以这么理解这一点,(大量的计算机意味着)大量的…

    Linux 2023年6月7日
    0100
  • 在公司当上PD的心路历程

    前不久因为接了个新项目,我被选中当上PD也就是专门负责给客户演示,推进项目、录视频、写文档、做测试,因为我本来就需要测这些东西,熟悉算法、应用、固件,所以大部分人就觉得非我不可。 …

    Linux 2023年6月8日
    095
  • 我叫Mongo,干了「查询终结篇」,值得您拥有

    这是mongo第三篇”查终结篇”,后续会连续更新5篇 mongodb的文章总结上会有一系列的文章,顺序是先学会怎么用,在学会怎么用好,戒急戒躁,循序渐进,跟…

    Linux 2023年6月14日
    0121
  • cpp-变量

    1.枚举类型 枚举类型是用户自定义的类型,在定义时要列举出该枚举类型所有的数值。 定义格式如下: [enum] enumName {val1, val2, val3} 其中的通常为…

    Linux 2023年6月7日
    084
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球