BZOJ 1012 [JSOI2008]最大数maxnumber
1012: [JSOI2008]最大数maxnumber
Time Limit: 3 Sec Memory Limit: 162 MB
Submit: 5425 Solved: 2397
[Submit][Status][Discuss]
Description
现在请求你维护一个数列,要求提供以下两种操作: 1、 查询操作。语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值。限制:L不超过当前数列的长度。 2、 插入操作。语法:A n 功能:将n加上t,其中t是最近一次查询操作的答案(如果还未执行过查询操作,则t=0),并将所得结果对一个固定的常数D取模,将所得答案插入到数列的末尾。限制:n是非负整数并且在长整范围内。注意:初始时数列是空的,没有一个数。
Input
第一行两个整数,M和D,其中M表示操作的个数(M <= 200,000),D如上文中所述,满足(0
Output
对于每一个查询操作,你应该按照顺序依次输出结果,每个结果占一行。
Sample Input
A 96
Q 1
A 97
Q 1
Q 2
Sample Output
93
96
HINT
Source
题解:先写个线段树拿分再说。不过我的处理方式很奇怪?不过幸好常数小。。。
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<queue> 6 #include<cstring> 7 #define PAU putchar(' ') 8 #define ENT putchar('\n') 9 #define CH for(int d=0;d<2;d++) if(ch[d]) 10 #define lson x->ch[0],L,M 11 #define rson x->ch[1],M+1,R 12 using namespace std; 13 const int maxn=200000+10,maxnode=400000+10,inf=-1u>>1; 14 int mod,last,ql,qr,pos,cv,_mx,n,len=0; 15 struct node{ 16 node*ch[2];int mx;node(){mx=-inf;} 17 void update(){mx=-inf;CH{if(ch[d]->mx>mx)mx=ch[d]->mx;}return;} 18 }seg[maxnode],*nodecnt=seg,*root; 19 void build(node*&x=root,int L=1,int R=n){ 20 x=nodecnt++;if(L==R)return;int M=L+R>>1;build(lson);build(rson);return; 21 } 22 void update(node*&x,int L,int R){ 23 if(L==R){x->mx=cv;return;}int M=L+R>>1; 24 if(pos<=M)update(lson);else update(rson);x->update(); 25 } 26 void query(node*x,int L,int R){ 27 if(ql<=L&&R<=qr){_mx=max(_mx,x->mx);return;}int M=L+R>>1; 28 if(ql<=M)query(lson);if(qr>M)query(rson);return; 29 } 30 inline int read(){ 31 int x=0,sig=1;char ch=getchar(); 32 while(!isdigit(ch)){if(ch=='-') sig=-1;ch=getchar();} 33 while(isdigit(ch)) x=10*x+ch-'0',ch=getchar(); 34 return x*sig; 35 } 36 inline void write(int x){ 37 if(x==0){putchar('0');return;}if(x<0) putchar('-'),x=-x; 38 int len=0,buf[15];while(x) buf[len++]=x%10,x/=10; 39 for(int i=len-1;i>=0;i--) putchar(buf[i]+'0');return; 40 } 41 inline char readc(){ 42 char ch=getchar();for(;!isalpha(ch);ch=getchar());return ch; 43 } 44 void init(){ 45 n=read();mod=read();build(); 46 for(int i=1;i<=n;i++){ 47 if(readc()=='A')cv=(last+read())%mod,len++,pos=len,update(root,1,n); 48 else{ 49 _mx=-inf;ql=len-read()+1;qr=len;query(root,1,n);write(_mx);ENT;last=_mx; 50 } 51 } 52 return; 53 } 54 void work(){ 55 return; 56 } 57 void print(){ 58 return; 59 } 60 int main(){ 61 init();work();print();return 0; 62 }
当然这道题还有一个神奇的做法:观察到如果一个数出现在某个数后边,并且这个数大于之前的数,那么之前的数无论如何也不会成为最大的数的。
所以我们可以维护一个单调的东西。然后就没有然后了。
还有,以后别写二分了!!!!!!!
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<queue> 6 #include<cstring> 7 #define PAU putchar(' ') 8 #define ENT putchar('\n') 9 using namespace std; 10 const int maxn=200000+10,inf=-1u>>1; 11 int s[maxn],top=0,n,mod,v[maxn],len=0,last; 12 inline int read(){ 13 int x=0,sig=1;char ch=getchar(); 14 while(!isdigit(ch)){if(ch=='-') sig=-1;ch=getchar();} 15 while(isdigit(ch)) x=10*x+ch-'0',ch=getchar(); 16 return x*=sig; 17 } 18 inline void write(int x){ 19 if(x==0){putchar('0');return;}if(x<0) putchar('-'),x=-x; 20 int len=0,buf[15];while(x) buf[len++]=x%10,x/=10; 21 for(int i=len-1;i>=0;i--) putchar(buf[i]+'0');return; 22 } 23 inline char readc(){ 24 char ch=getchar();for(;!isalpha(ch);ch=getchar());return ch; 25 } 26 void init(){ 27 n=read();mod=read(); 28 for(int i=1;i<=n;i++){ 29 if(readc()=='A'){ 30 int cv=(read()+last)%mod; 31 v[++len]=cv; 32 while(top&&v[s[top]]<=cv)top--; 33 s[++top]=len; 34 } else { 35 int pos=lower_bound(s+1,s+top+1,len-read()+1)-s; 36 write(last=v[s[pos]]);ENT; 37 } 38 } 39 return; 40 } 41 void work(){ 42 return; 43 } 44 void print(){ 45 return; 46 } 47 int main(){ 48 init();work();print();return 0; 49 }
GYH神犇还提出了离线RMQ的思想。可以发现,每一次插入数即为新建一个集合,而删除一个数即将两集合合并,每次询问则为查询一个数所在的集合的代表元素。这正好是并查集所支持的各种操作。而并查集的每次操作的均摊复杂度接近O(1),所以RMQ的离线问题也可以在O(N+Q)的时间内解决,空间复杂度也是O(N+Q)。
但是。。。这个跟普通的二分跑得差不多,不过代码复杂度少了很多。
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<queue> 6 #include<cstring> 7 #define PAU putchar(' ') 8 #define ENT putchar('\n') 9 using namespace std; 10 const int maxn=200000+10; 11 int stack[maxn],top=0,fa[maxn],A[maxn]; 12 int find(int x){if(fa[x]==x)return x;return fa[x]=find(fa[x]);} 13 inline int read(){ 14 int x=0,sig=1;char ch=getchar(); 15 while(!isdigit(ch)){if(ch=='-') sig=-1;ch=getchar();} 16 while(isdigit(ch)) x=10*x+ch-'0',ch=getchar(); 17 return x*=sig; 18 } 19 inline void write(int x){ 20 if(x==0){putchar('0');return;}if(x<0) putchar('-'),x=-x; 21 int len=0,buf[15];while(x) buf[len++]=x%10,x/=10; 22 for(int i=len-1;i>=0;i--) putchar(buf[i]+'0');return; 23 } 24 inline char readc(){ 25 char ch=getchar();while(!isalpha(ch))ch=getchar();return ch; 26 } 27 void init(){ 28 int last=0,m,mod,x,len=0; 29 m=read();mod=read(); 30 for(int i=1;i<=m;i++) fa[i]=i; 31 while(m--){ 32 if(readc()=='Q')x=(len-read()),write(last=A[find(x)]),ENT; 33 else{ 34 A[len]=(last+read())%mod; 35 while(top&&A[stack[~-top]]<=A[len])fa[stack[--top]]=len; 36 stack[top++]=len++; 37 } 38 } 39 return; 40 } 41 void work(){ 42 return; 43 } 44 void print(){ 45 return; 46 } 47 int main(){init();work();print();return 0;}
转载于:https://www.cnblogs.com/chxer/p/4644654.html
BZOJ 1012 [JSOI2008]最大数maxnumber相关推荐
- BZOJ 1012: [JSOI2008]最大数maxnumber 单调队列/线段树/树状数组/乱搞
1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec Memory Limit: 162 MB Submit: 4750 Solved: 2145 [Sub ...
- BZOJ 1012: [JSOI2008]最大数maxnumber
1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec Memory Limit: 162 MB Submit: 11358 Solved: 4978 [Su ...
- BZOJ 1012: [JSOI2008]最大数maxnumber(线段树)
裸的线段树...因为数组开小了而一直RE..浪费了好多时间.. -------------------------------------------------------------------- ...
- 1012: [JSOI2008]最大数maxnumber
1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec Memory Limit: 162 MB Submit: 10711 Solved: 4683 [Su ...
- 【BZOJ】1012: [JSOI2008]最大数maxnumber 树状数组求区间最值
题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1012 题意:维护一个数列,开始时没有数值,之后会有两种操作, Q L :查询数列末 ...
- 1012: [JSOI2008]最大数maxnumber 线段树
https://www.lydsy.com/JudgeOnline/problem.php?id=1012 现在请求你维护一个数列,要求提供以下两种操作:1. 查询操作.语法:Q L 功能:查询当前数 ...
- 【BZOJ 1012】[JSOI2008]最大数maxnumber
1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec Memory Limit: 162 MB Description 现在请求你维护一个数列,要求提供以下两种 ...
- BZOJ-1012[JSOI2008]最大数maxnumber 线段树区间最值
这道题相对简单下面是题目: 1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec Memory Limit: 162 MB Submit: 6542 Solve ...
- 【bzoj1012】[JSOI2008]最大数maxnumber st表
Description 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作.语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度. 2. ...
最新文章
- 「镁客早报」任正非称对苹果等对手出售5G芯片持开放态度;马斯克称未来12个月内将生产超过50万辆车...
- 一加nfc门禁卡录入_忘记门禁卡不再徘徊 一加7T多功能NFC过来拯救你
- Activiti中的关于子流程中的并发节点标记处理
- Python --- 卸载
- (王道408考研数据结构)第二章线性表-第三节5:顺序表和链表的比较
- flask 接口上传文件_Flask干货:Flask数据交换——上传文件
- Photoshop和WPF双剑配合,打造炫酷个性的进度条控件
- Python-读取本地视频转化为图片方法记录(一)
- 【git】git的删除命令与如何删除仓库文件的方法
- python将一句话重复n次输出_在Python中创建单项重复n次的列表
- 前端判断是微信浏览器还是qq还是微信浏览器
- 6 计算机网络 待更新
- ubuntu14.04安装nvidia-GTK-1060驱动后黑屏
- 白领的一天 场景7:薪水与福利
- OpenGL入门:窗口开启、改变窗口背景颜色
- TensorFlow及深度学习相关资料积累汇总【不定期更新】
- 千里之行始于足下 | 开篇 - 增长极客
- C++类和对象介绍(筑基上篇)
- 【动画】css实现旋转和平移效果
- Ubuntu16.04+1080ti显卡驱动安装流程+循环登录问题【集锦】
热门文章
- can not open file Permission denied at securecrt_linux_crack.pl line 57
- Flink SQL Client的datagen的用法(转载+自己验证)
- 一些没啥用的大数据组件以及理由(持续更新中)+2020的Gartner曲线
- Gauss-Newton算法代码详细解释(转载+自己注释)
- A little something to get you started
- NLTK频率分类中定义的函数
- opengl glad.h和 glu.h
- 图像工程 CH6图像校正和修补
- ROS总结一,catkin,package,CMakeList,Topic,node
- 窗体测试只能用于本地测试_爆料:微软 Win10X 将首先用于测试单屏笔记本