[NOI2005] 维护数列(fhq-Treap)
来源:互联网 发布:js判断弹出提示框 编辑:程序博客网 时间:2024/06/05 10:25
【问题描述】
请写一个程序,要求维护一个数列,支持以下 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 82 -6 3 5 1 -5 -3 6 3GET-SUM 5 4MAX-SUM INSERT 8 3 -5 7 2DELETE 12 1MAKE-SAME 3 3 2REVERSE 3 6GET-SUM 5 4MAX-SUM
【输出样例】
-110110
【样例说明】
初始时,我们拥有数列 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-6351-5-36-572
改为
2-6222-5-36-572
执行操作 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。
#include<iostream>#include<cstdio>#include<cstdlib>#include<algorithm>#define key(x)(x?x->v:0)#define sz(x)(x?x->s:0)#define sl(x)(x?x->lmax:0)#define sr(x)(x?x->rmax:0)#define sm(x)(x?x->ma:-0x3fffffff)#define ss(x)(x?x->sum:0)#define ssr(x)(x?x->rmax:-0x3fffffff)#define ssl(x)(x?x->lmax:-0x3fffffff)#define sss(x)(x?x->sum:-0x3fffffff)#define skey(x)(x?x->v:-0x3fffffff)using namespace std;inline int read(){ char c=getchar();int x=0,y=1;while(c<'0'||c>'9'){if(c=='-') y=-1;c=getchar();}while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();return x*y;}int n,m,inf=0x3fffffff;struct Treap{int v,r,s,mk,sum,lmax,rmax,ma,se;Treap *ch[2];Treap(int x):v(x){ch[0]=ch[1]=NULL;s=1;se=-inf;r=rand();sum=lmax=rmax=ma=v;mk=0;}void revs(){if(this){mk^=1;swap(ch[0],ch[1]);swap(lmax,rmax);}}void addv(int x){if(this){se=x;v=x;sum=x*s;lmax=rmax=ma=max(x,sum);}}void dn(){if(this){if(mk){if(ch[0]) ch[0]->revs(); if(ch[1]) ch[1]->revs();mk=0;}if(se!=-inf){ if(ch[0]) ch[0]->addv(se);if(ch[1]) ch[1]->addv(se);se=-inf;}}}void mt(){if(this){s=1+sz(ch[0])+sz(ch[1]);sum=v+ss(ch[0])+ss(ch[1]); lmax=max(ssl(ch[0]),max(ss(ch[0])+v+sl(ch[1]),ss(ch[0])+v)); rmax=max(ssr(ch[1]),max(ss(ch[1])+v+sr(ch[0]),ss(ch[1])+v)); ma=max(max(sm(ch[0]),sm(ch[1])),max(sr(ch[0])+v+sl(ch[1]),max(max(sr(ch[0])+v,sl(ch[1])+v),v))); }}~Treap(){if(this->ch[0]) delete this->ch[0];if(this->ch[1]) delete this->ch[1];}}*root;typedef pair<Treap*,Treap*> dt;Treap* merge(Treap* x,Treap* y){if(!x) return y;if(!y) return x;if(x->r < y->r){x->dn();x->ch[1]=merge(x->ch[1],y);x->mt();return x;}else{y->dn();y->ch[0]=merge(x,y->ch[0]);y->mt();return y;}}dt split(Treap* x,int k){if(!x) return dt(NULL,NULL);dt y;x->dn();if(sz(x->ch[0])>=k) y=split(x->ch[0],k),x->ch[0]=y.second,x->mt(),y.second=x;else y=split(x->ch[1],k-sz(x->ch[0])-1),x->ch[1]=y.first,x->mt(),y.first=x;return y;}Treap* build(int len){Treap* *st=new Treap*[len];Treap *las,*x,*ans;int tail=0,tmp;for(int i=1;i<=len;i++){tmp=read();x=new Treap(tmp);las=NULL;while(tail&&st[tail-1]->r > x->r){st[tail-1]->mt();las=st[tail-1];st[--tail]=NULL;}if(tail) st[tail-1]->ch[1]=x;x->ch[0]=las;st[tail++]=x;}while(tail) st[--tail]->mt();ans=st[0];delete []st;return ans;}void insert(int k,int len){Treap *tmp=build(len);dt t2=split(root,k);root=merge(t2.first,merge(tmp,t2.second));}void del(int k,int len){dt x,y;x=split(root,k-1);y=split(x.second,len);root=merge(x.first,y.second);delete y.first;y.first=NULL;}void reve(int k,int len){dt x,y;x=split(root,k-1);y=split(x.second,len);y.first->revs();root=merge(x.first,merge(y.first,y.second));}void updata(int k,int len,int val){dt x,y;x=split(root,k-1);y=split(x.second,len);y.first->addv(val);root=merge(x.first,merge(y.first,y.second));}void gsum(int k,int len){dt x,y;x=split(root,k-1);y=split(x.second,len);printf("%d\n",ss(y.first));root=merge(x.first,merge(y.first,y.second));}void cmp(Treap* x,Treap* y,Treap* &z){if(z){z->s=sz(x)+sz(y)+1; z->sum=ss(x)+ss(y)+key(z); z->lmax=max(ssl(x),max(ss(x)+sl(y)+key(z),ss(x)+key(z))); z->rmax=max(ssr(y),max(ss(y)+sr(x)+key(z),ss(y)+key(z))); z->ma=max(max(sm(x),sm(y)),max(sr(x)+sl(y)+key(z),max(sr(x)+key(z),max(sl(y)+key(z),key(z)))));}}int main(){freopen("seq2005.in","r",stdin);freopen("seq2005.out","w",stdout);scanf("%d%d",&n,&m);root=build(n);char ord[20];int x,y,z;for(int i=1;i<=m;i++){scanf("%s",ord);if(ord[0]=='I'){scanf("%d%d",&x,&y);insert(x,y);}if(ord[0]=='D'){scanf("%d%d",&x,&y);del(x,y);}if(ord[0]=='M'&&ord[2]=='K'){scanf("%d%d%d",&x,&y,&z);updata(x,y,z);}if(ord[0]=='R'){scanf("%d%d",&x,&y);reve(x,y);}if(ord[0]=='G'){scanf("%d%d",&x,&y);gsum(x,y);}if(ord[0]=='M'&&ord[2]=='X') printf("%d\n",root->ma);}return 0;}
- [NOI2005] 维护数列(fhq-Treap)
- [noi2005][treap]序列维护
- 【noi2005】维护数列
- [NOI2005] 维护数列 sequence
- 【NOI2005】【splay】维护数列
- 数列维护 NOI2005
- 【SPLAY】NOI2005 维护数列
- 【noi2005】维护数列
- NOI2005维护数列
- noi2005维护数列 splay
- JZOJ2413. 【NOI2005】维护数列
- 【NOI2005】维护数列
- 【NOI2005】维护数列
- [NOI2005] 维护数列
- [题解]NOI2005 维护数列
- noi2005维护数列
- 【NOI2005】维护数列(BSOI2246)
- JZOJ2413 【NOI2005】维护数列
- PyQt5学习记录(5)---QDockWidget和QListWidget的基础综合使用
- Thread,Looper,Handler,Message,MessageQueue原理机制以及它们之间的关系
- Spring自定义属性编辑器——2
- UBOOT主makefile流程分析
- 类似于QQ聊天界面的EditView输入控件点击获取焦点弹出软件盘,点击屏幕使EditView失去焦点隐藏软件盘。
- [NOI2005] 维护数列(fhq-Treap)
- laravle 中 validate 汉化
- 大素数判定板子
- C# 动态调用WebService
- 包(package)
- async函数基础
- C++修饰符----继承
- 事务管理之Spring事务管理
- 动态规划总结与题目分类