339. [NOI2005] 维护数列
时间限制:3 s   内存限制:256 MB

【问题描述】

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

操作编号

输入文件中的格式

说明

1.  插入

INSERT_posi_tot_c1_c2_..._ctot

在当前数列的第 posi 个数字后插入 tot

个数字:c1, c2, …, ctot;若在数列首插

入,则 posi 为 0

2.  删除

DELETE_posi_tot

从当前数列的第 posi 个数字开始连续

删除 tot 个数字

3.  修改

MAKE-SAME_posi_tot_c

将当前数列的第 posi 个数字开始的连

续 tot 个数字统一修改为 c

4.  翻转

REVERSE_posi_tot

取出从当前数列的第 posi 个数字开始

的 tot 个数字,翻转后放入原来的位置

5.  求和

GET-SUM_posi_tot

计算从当前数列开始的第 posi 个数字

开始的 tot 个数字的和并输出

6.  求和最

大的子列

MAX-SUM

求出当前数列中和最大的一段子列,

并输出最大和

【输入格式】

输入文件的第 1 行包含两个数 N 和 M,N 表示初始时数列中数的个数,M表示要进行的操作数目。

第 2 行包含 N 个数字,描述初始时的数列。

以下 M 行,每行一条命令,格式参见问题描述中的表格。

【输出格式】

对于输入数据中的 GET-SUM 和 MAX-SUM 操作,向输出文件依次打印结果,每个答案(数字)占一行。

【输入样例】

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

【输出样例】

-1
10
1
10

【样例说明】

初始时,我们拥有数列 2 -6 3 5 1 -5 -3 6 3

执行操作 GET-SUM 5 4,表示求出数列中从第 5 个数开始连续 4 个数字之和,1+(-5)+(-3)+6 = -1:

2     -6     3      5      1     -5    -3     6      3

执行操作 MAX-SUM,表示要求求出当前数列中最大的一段和,应为 3+5+1+(-5)+(-3)+6+3 = 10:

2     -6     3      5      1     -5    -3     6      3

执行操作 INSERT 8 3 -5 7 2,即在数列中第 8 个数字后插入-5 7 2,

2     -6     3      5      1     -5    -3     6     -5     7      2      3

执行操作 DELETE 12 1,表示删除第 12 个数字,即最后一个:

2     -6     3      5      1     -5    -3     6     -5     7      2

执行操作 MAKE-SAME 3 3 2,表示从第 3 个数开始的 3 个数字,统一修改为 2:

2  -6  3   5   1   -5  -3  6   -5  7   2

改为

2 -6  2   2   2   -5  -3  6   -5  7   2

执行操作 REVERSE 3 6,表示取出数列中从第 3 个数开始的连续 6 个数:

2           -6            2             2             2           -5            -3            6            -5            7            2

如上所示的灰色部分 2 2 2 -5 -3 6,翻转后得到 6 -3 -5 2 2 2,并放回原来位置:

2     -6     6     -3     -5     2      2      2     -5     7      2

最后执行 GET-SUM 5 4 和 MAX-SUM,不难得到答案 1 和 10。

2            -6            6            -3            -5           2             2            2             -5           7             2

【评分方法】

本题设有部分分,对于每一个测试点:

  • 如果你的程序能在输出文件正确的位置上打印 GET-SUM 操作的答案,你可以得到该测试点 60%的分数;
  • 如果你的程序能在输出文件正确的位置上打印 MAX-SUM 操作的答案,你可以得到该测试点 40%的分数;
  • 以上两条的分数可以叠加,即如果你的程序正确输出所有 GET-SUM 和MAX-SUM 操作的答案,你可以得到该测试点 100%的分数。

请注意:如果你的程序只能正确处理某一种操作,请确定在输出文件正确的位置上打印结果,即必须为另一种操作留下对应的行,否则我们不保证可以正确评分。

【数据规模和约定】

  • 你可以认为在任何时刻,数列中至少有 1 个数。
  • 输入数据一定是正确的,即指定位置的数在数列中一定存在。
  • 50%的数据中,任何时刻数列中最多含有 30 000 个数;
  • 100%的数据中,任何时刻数列中最多含有 500 000 个数。
  • 100%的数据中,任何时刻数列中任何一个数字均在[-1 000, 1 000]内。
  • 100%的数据中,M ≤20 000,插入的数字总数不超过 4 000 000 个,输入文件大小不超过 20MBytes。

  这道题需要注意细节,写之前请理清思路!!!

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 using namespace std;
  5 const int maxn=5000010;
  6 const int INF=1000000000;
  7 int fa[maxn],ch[maxn][2],sz[maxn],key[maxn];
  8 int mark[maxn],flip[maxn],sum[maxn],n,Q;
  9 int lx[maxn],rx[maxn],mx[maxn],rt,cnt;
 10 char s[15];
 11 void Push_up(int x){
 12     sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;
 13     sum[x]=sum[ch[x][0]]+sum[ch[x][1]]+key[x];
 14     lx[x]=max(lx[ch[x][0]],key[x]+sum[ch[x][0]]+lx[ch[x][1]]);
 15     rx[x]=max(rx[ch[x][1]],key[x]+sum[ch[x][1]]+rx[ch[x][0]]);
 16     mx[x]=max(max(mx[ch[x][0]],mx[ch[x][1]]),key[x]+rx[ch[x][0]]+lx[ch[x][1]]);
 17 }
 18
 19 void Cover(int x,int d){
 20     if(!x)return;
 21     key[x]=d;mark[x]=1;
 22     sum[x]=sz[x]*d;
 23     if(d>0)lx[x]=rx[x]=mx[x]=sum[x];
 24     else lx[x]=rx[x]=0,mx[x]=d;
 25 }
 26
 27 void Flip(int x){
 28     if(!x)return;
 29     swap(ch[x][0],ch[x][1]);
 30     swap(lx[x],rx[x]); //mod Kuang_bin
 31     flip[x]^=1;
 32 }
 33
 34 void Push_down(int x){
 35     if(mark[x]){
 36         Cover(ch[x][0],key[x]);
 37         Cover(ch[x][1],key[x]);
 38         mark[x]=0;
 39     }
 40     if(flip[x]){
 41         Flip(ch[x][0]);
 42         Flip(ch[x][1]);
 43         flip[x]=0;
 44     }
 45 }
 46
 47 void Rotate(int x){
 48     int y=fa[x],g=fa[y],c=ch[y][1]==x;
 49     ch[y][c]=ch[x][c^1];fa[ch[y][c]]=y;
 50     ch[x][c^1]=y;fa[y]=x;fa[x]=g;
 51     if(g)ch[g][ch[g][1]==y]=x;
 52     Push_up(y);
 53 }
 54
 55 void Splay(int x,int g=0){
 56     for(int y;(y=fa[x])!=g;Rotate(x))
 57         if(fa[y]!=g)
 58             Rotate((ch[fa[y]][1]==y)==(ch[y][1]==x)?y:x);
 59     if(!g)rt=x;
 60     Push_up(x);
 61 }
 62
 63 void Rtr(int k,int g=0){
 64     int p=rt;
 65     while(true){
 66         Push_down(p);
 67         if(sz[ch[p][0]]+1==k)break;
 68         if(sz[ch[p][0]]+1<k){
 69             k-=sz[ch[p][0]]+1;
 70             p=ch[p][1];
 71         }
 72         else
 73             p=ch[p][0];
 74     }
 75     Splay(p,g);
 76 }
 77
 78 int Insert(int x,int l,int r){
 79     int mid=(l+r)>>1,p=++cnt;
 80     fa[p]=x;sz[p]=1;
 81     if(l<mid)ch[p][0]=Insert(p,l,mid-1);
 82     scanf("%d",&key[p]);
 83     if(r>mid)ch[p][1]=Insert(p,mid+1,r);
 84     Push_up(p);
 85     return p;
 86 }
 87
 88 void Init(){
 89     cnt=2;rt=1;
 90     mx[1]=mx[2]=-INF;
 91     fa[2]=1;ch[1][1]=2;
 92     ch[ch[rt][1]][0]=Insert(ch[rt][1],1,n);
 93     Push_up(ch[rt][1]);
 94     Push_up(rt);
 95 }
 96
 97 int main(){
 98     freopen("seq2005.in","r",stdin);
 99     freopen("seq2005.out","w",stdout);
100     scanf("%d%d",&n,&Q);
101     Init();mx[0]=-INF;
102     int l,r,x,d,tot=n+2;
103     while(Q--){
104         scanf("%s",s);
105         if(!strcmp(s,"MAX-SUM")){
106             Rtr(1);
107             Rtr(tot,rt);
108             Push_down(rt);
109             Push_down(ch[rt][1]);
110             printf("%d\n",mx[ch[ch[rt][1]][0]]);
111         }
112         else if(!strcmp(s,"INSERT")){
113             scanf("%d%d",&l,&x);l+=1;
114             Rtr(l);Rtr(l+1,rt);
115             Push_down(rt);tot+=x;
116             Push_down(ch[rt][1]);
117             ch[ch[rt][1]][0]=Insert(ch[rt][1],1,x);
118             Push_up(ch[rt][1]);
119             Push_up(rt);
120         }
121         else if(!strcmp(s,"DELETE")){
122             scanf("%d%d",&l,&x);r=l+x+1;
123             Rtr(l);Rtr(r,rt);tot-=x;
124             ch[ch[rt][1]][0]=0;
125             Push_up(ch[rt][1]);
126             Push_up(rt);
127         }
128         else if(!strcmp(s,"REVERSE")){
129             scanf("%d%d",&l,&x);r=l+x+1;
130             Rtr(l);Rtr(r,rt);
131             Flip(ch[ch[rt][1]][0]);
132             Push_up(ch[rt][1]);
133             Push_up(rt);
134         }
135         else if(!strcmp(s,"MAKE-SAME")){
136             scanf("%d%d%d",&l,&x,&d);r=l+x+1;
137             Rtr(l);Rtr(r,rt);
138             Push_down(rt);
139             Push_down(ch[rt][1]);
140             Cover(ch[ch[rt][1]][0],d);
141             Push_up(ch[rt][1]);
142             Push_up(rt);
143         }
144         else if(!strcmp(s,"GET-SUM")){
145             scanf("%d%d",&l,&x);r=l+x+1;
146             Rtr(l);Rtr(r,rt);
147             Push_down(rt);
148             Push_down(ch[rt][1]);
149             printf("%d\n",sum[ch[ch[rt][1]][0]]);
150         }
151     }
152     return 0;
153 }

转载于:https://www.cnblogs.com/TenderRun/p/5349752.html

数据结构(Splay平衡树):COGS 339. [NOI2005] 维护数列相关推荐

  1. BZOJ 1500 Luogu P2042 [NOI2005] 维护数列 (Splay)

    BZOJ 1500 Luogu P2042 [NOI2005] 维护数列 (Splay) 手动博客搬家: 本文发表于20180825 00:34:49, 原地址https://blog.csdn.ne ...

  2. [NOI2005]维护数列 恶心到毁天灭地的splay

    传送门 debug到死2333. 虽然说是splay维护序列模板,作为蒟蒻的我还是GG %%%考场A的dalao Orz  Orz. 其实不开long long也行,inf开成0x3f3f3f3f也可 ...

  3. [NOI2005]维护数列

    输入格式 输入文件的第 1 行包含两个数 N 和 M,N 表示初始时数列中数的个数,M 表示要进行的操作数目. 第 2 行包含 N 个数字,描述初始时的数列. 以下 M 行,每行一条命令,格式参见问题 ...

  4. [luogu2042] [NOI2005]维护数列

    前言 写写比较麻烦的这题 题目相关 题目大意 写一个大数据结构 数据范围 20000 题目链接 前置 先过模板题,比如会个非旋treap,写一下,通过[luogu3369][模板]普通平衡树 poss ...

  5. [BZOJ1500][NOI2005]维修数列(splay)

    1500: [NOI2005]维修数列 Time Limit: 10 Sec  Memory Limit: 64 MB Submit: 16266  Solved: 5410 [Submit][Sta ...

  6. 数据结构之fhq-treap——Chef and Sets,[HNOI2012]永无乡,Play with Chain,[NOI2005]维修数列(结构体版代码)

    因为非常板,所以主要是代码 Tyvj 1728 普通平衡树 Chef and Sets [HNOI2012]永无乡 Play with Chain [NOI2005]维修数列 题目很水,所以可能会出现 ...

  7. 【BZOJ1500】[NOI2005]维修数列 Splay

    [BZOJ1500][NOI2005]维修数列 Description Input 输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目. 第2 ...

  8. [BZOJ 1500] [NOI2005] 维修数列

    题目链接:BZOJ - 1500 题目分析 我要先说一下,这道题我写了一晚上,然后Debug了一整个白天..........再一次被自己的蒟蒻程度震惊= = 这道题是传说中的Splay维护数列的Bos ...

  9. Interview:算法岗位面试—上海某公司算法岗位(偏机器学习,互联网金融行业)技术面试考点之数据结构相关考察点—斐波那契数列、八皇后问题、两种LCS问题

    ML岗位面试:上海某公司算法岗位(偏机器学习,互联网金融行业)技术面试考点之数据结构相关考察点-斐波那契数列.八皇后问题.两种LCS问题 Interview:算法岗位面试-上海某公司算法岗位(偏机器学 ...

最新文章

  1. 爬虫之数据提取jsonpath模块的使用场景和使用方法
  2. 因融资失败,应用崩溃,3 名程序员被“祭天”!
  3. 冬眠动物克服肌肉萎缩,靠的居然是“肠子”|Science
  4. springboot启动后进页面出现错误(java.sql.SQLNonTransientConnectionException: CLIENT_PLUGIN_AUTH is required)
  5. Java线程池Executor框架
  6. python做自动化测试的优点_乐搏讲自动化测试-python语言特点及优缺点(5)
  7. php怎样连接上数据库服务器,php怎样连接数据库
  8. 二分+BFS——刺杀大使(洛谷 P1902)
  9. mysql 进阶到高级_MySQL 高级(进阶) SQL 语句精讲(一)
  10. 华语歌坛年度压轴 王力宏新专辑《心中的日月》
  11. JavaScript原型、函数伪装(apply,call)、继承
  12. Python(二):基本数据类型、序列的基本操作
  13. 安装更多的CAD字体
  14. .net rdlc 自定义函数把数字转换为大写中文
  15. 【转载】NURBS概念
  16. 颠覆想象,一盏夜灯的变革
  17. maven 中配置多个mirror的问题
  18. Java 如何判断一个字符串中是否包含某一 子字符串
  19. perror()函数 strerror()函数 详解
  20. 计算机集成制造相关文献,计算机集成制造专著类参考文献 计算机集成制造期刊参考文献哪里找...

热门文章

  1. 未与信任 SQL Server 连接相关联
  2. 关于从EXCEL中导入到SQL server中的问题
  3. 要做互联星空的SP接口,一点头绪都没有
  4. Flutter自定义相机,Flutter相册选择照片
  5. vue中v-bind指令的使用之Vue知识点归纳(七)
  6. sqlserver创建程序集
  7. Oralce的内存结构
  8. 研究大华3G设备接入自主视频开发平台
  9. 归纳(四):树链剖分
  10. 红帽Linux故障定位技术详解与实例(3)