P1198 [JSOI2008]最大数
题目描述
现在请求你维护一个数列,要求提供以下两种操作:
1、 查询操作。
语法:Q L
功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值。
限制:L不超过当前数列的长度。(L>0)
2、 插入操作。
语法:A n
功能:将n加上t,其中t是最近一次查询操作的答案(如果还未执行过查询操作,则t=0),并将所得结果对一个固定的常数D取模,将所得答案插入到数列的末尾。
限制:n是整数(可能为负数)并且在长整范围内。
注意:初始时数列是空的,没有一个数。
输入输出格式
输入格式:
第一行两个整数,M和D,其中M表示操作的个数(M≤200,000),D如上文中所述,满足(0<D<2,000,000,000)
接下来的M行,每行一个字符串,描述一个具体的操作。语法如上文所述。
输出格式:
对于每一个查询操作,你应该按照顺序依次输出结果,每个结果占一行。
输入输出样例
5 100
A 96
Q 1
A 97
Q 1
Q 2
96
93
96
说明
[JSOI2008]
本题数据已加强
Solution:
本题动态开点线段树板子题。
因为最多$2*10^5$次操作,所以最多就$2*10^5$个叶节点,每次加数都动态开点,然后维护区间max就好了。
代码:
/*Code by 520 -- 9.25*/
#include<bits/stdc++.h>
#define il inline
#define ll long long
#define RE register
#define For(i,a,b) for(RE int (i)=(a);(i)<=(b);(i)++)
#define Bor(i,a,b) for(RE int (i)=(b);(i)>=(a);(i)--)
using namespace std;
const int N=;
int n,p,lst;
struct node{
int l,r,maxn;
}t[N<<]; int gi(){
int a=;char x=getchar();bool f=;
while((x<''||x>'')&&x!='-') x=getchar();
if(x=='-') x=getchar(),f=;
while(x>=''&&x<='') a=(a<<)+(a<<)+(x^),x=getchar();
return f?-a:a;
} il void pushup(int rt){t[rt].maxn=max(t[rt<<].maxn,t[rt<<|].maxn);} void build(int l,int r,int rt){
t[rt].l=l,t[rt].r=r;
if(l==r) return;
int m=l+r>>;
build(l,m,rt<<),build(m+,r,rt<<|);
} void update(int k,int x,int rt){
if(t[rt].l==t[rt].r) {t[rt].maxn=x;return;}
int m=t[rt].l+t[rt].r>>;
if(k<=m) update(k,x,rt<<);
else update(k,x,rt<<|);
pushup(rt);
} int query(int L,int R,int rt){
if(t[rt].l>=L&&t[rt].r<=R) return t[rt].maxn;
int m=t[rt].l+t[rt].r>>,maxn=-0x3f3f3f3f;
if(L<=m) maxn=max(maxn,query(L,R,rt<<));
if(R>m) maxn=max(maxn,query(L,R,rt<<|));
return maxn;
} int main(){
char opt[];int x,cnt=;
n=gi(),p=gi();
build(,n,);
For(i,,n){
scanf("%s",opt),x=gi();
if(opt[]=='A') update(++cnt,(x+lst)%p,);
else printf("%d\n",lst=query(cnt-x+,cnt,));
}
return ;
}
当然本题也可以用无旋treap来写,对于查询操作直接分离区间并维护区间最大值就好了。
代码:
/*Code by 520 -- 9.27*/
#include<bits/stdc++.h>
#define il inline
#define ll long long
#define RE register
#define For(i,a,b) for(RE int (i)=(a);(i)<=(b);(i)++)
#define Bor(i,a,b) for(RE int (i)=(b);(i)>=(a);(i)--)
using namespace std;
const int N=;
int n,mod,root,cnt,lst;
struct node{
int ls,rs,siz,rnd,date,maxn;
}t[N]; int gi(){
int a=;char x=getchar();bool f=;
while((x<''||x>'')&&x!='-') x=getchar();
if(x=='-') x=getchar(),f=;
while(x>=''&&x<='') a=(a<<)+(a<<)+(x^),x=getchar();
return f?-a:a;
} il int newnode(int v){
++cnt;
t[cnt].siz=,t[cnt].date=t[cnt].maxn=v,t[cnt].rnd=rand();
return cnt;
} il void up(int rt){
t[rt].siz=t[t[rt].ls].siz+t[t[rt].rs].siz+;
t[rt].maxn=max(t[rt].date,max(t[t[rt].ls].maxn,t[t[rt].rs].maxn));
} int merge(int x,int y){
if(!x||!y) return x+y;
if(t[x].rnd<t[y].rnd) {t[x].rs=merge(t[x].rs,y),up(x);return x;}
else {t[y].ls=merge(x,t[y].ls),up(y);return y;}
} void split(int rt,int k,int &x,int &y){
if(!rt){x=y=;return;}
if(t[t[rt].ls].siz<k) x=rt,split(t[rt].rs,k-t[t[rt].ls].siz-,t[x].rs,y),up(x);
else y=rt,split(t[rt].ls,k,x,t[y].ls),up(y);
} int main(){
n=gi(),mod=gi();char s[];int v,x,y;
while(n--) {
scanf("%s",s),v=gi();
if(s[]=='A') root=merge(root,newnode((v+lst)%mod));
else {
x=y=; split(root,cnt-v,x,y);
printf("%d\n",lst=t[y].maxn);
root=merge(x,y);
}
}
return ;
}
P1198 [JSOI2008]最大数的更多相关文章
- 洛谷P1198 [JSOI2008]最大数
P1198 [JSOI2008]最大数 267通过 1.2K提交 题目提供者该用户不存在 标签线段树各省省选 难度提高+/省选- 提交该题 讨论 题解 记录 最新讨论 WA80的戳这QwQ BZOJ都 ...
- 洛谷 P1198 [JSOI2008]最大数
洛谷 P1198 [JSOI2008]最大数 题目描述 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值. ...
- P1198 [JSOI2008]最大数(单调栈)
P1198 [JSOI2008]最大数 题目描述 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值. 限制: ...
- P1198 [JSOI2008]最大数(线段树)
P1198 [JSOI2008]最大数(线段树) 题目描述 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值 ...
- 洛谷P1198 [JSOI2008]最大数(单点修改,区间查询)
洛谷P1198 [JSOI2008]最大数 简单的线段树单点问题. 问题:读入A和Q时,按照读入一个字符会MLE,换成读入字符串就可以了. #include<bits/stdc++.h> ...
- P1198 [JSOI2008]最大数(线段树基础)
P1198 [JSOI2008]最大数 题目描述 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值. 限制: ...
- 「线段树」「单点修改」洛谷P1198 [JSOI2008]最大数
「线段树」「单点修改」洛谷P1198 [JSOI2008]最大数 题面描述 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数, ...
- 洛谷P1198 [JSOI2008]最大数(BZOJ.1012 )
To 洛谷.1198 最大数 题目描述 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值. 限制:L不超过当 ...
- 洛谷 P1198 [JSOI2008]最大数 Label:线段树
题目描述 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值. 限制:L不超过当前数列的长度. 2. 插入操作 ...
- Luogu P1198 [JSOI2008]最大数
我会用高级(???)的单调栈来打这道题吗? 线段树即可水过. 假设这个数列刚开始所有数都是0,然后我们每次只要进行一个点的修改和区间求和即可. 这不就是 线段树大法. 只要用一个len记录一下当前数列 ...
随机推荐
- nodejs学习笔记(3)
在看了Node8的特性后的总结,后续慢慢补充. 主要是针对一些编码规范,Node的v8引擎由于不同于其他语言的解析策略,因此需要注意一些特殊的方面. 1.try/catch使用对代码运行性能影响明显, ...
- Print Spooler 服务自动停止
1)先在服务里停止并禁用Print Spooler : 2)删除此文件夹下的所有文件,C:\Windows\System32\spool\PRINTERS\ : 3)删除注册表 HKEY_LOCAL_ ...
- java学习(三)类、实例
类 public class Dog{ String breed; int age; String color; void barking(){ } void hungry(){ } void sle ...
- 第1章 Linux命令行简介
1.1 Linux命令行概述 1.2 在Linux命令行下查看命令帮助 1.3 Linux关机.重启.注销命令 1.4 老男孩的运维思想 1.1 Linux命令行概述 1.1.1 Linux命令行的作 ...
- python简单计时器实现
实现程序运行时间的显示与相互之间的计算: 实现代码: import time as t class Mytimer(): def __init__(self): self.unit=["年& ...
- X509证书申请以及PKCS#10 详解
一.证书颁发 1.单证书的签发 1) 用户填写信息注册(或者由RA的业务操作员注册用户). 2) 用户信息传递到RA. 3) RA审核通过. 4) 用户请求发证. 5) RA审核通过. 6) 用户签发 ...
- vmware安装androidx86 (FreeBSD) 系统图解
有时候自己手机的一些方面限制的因素,我们需要在电脑上装一个“手机”,来完成我们想要做的事情. 安装步骤如下: 首先需要一个ISO系统镜像,下面地址可以提供大量镜像下载: https://zh.osdn ...
- iOS 模块化、组件化方案探索(利用cocoapods 、git 创建私有仓库)
来自bang's blog http://blog.cnbang.net/tech/3080/ 模块化 简单来说,模块化就是将一个程序按照其功能做拆分,分成相互独立的模块,以便于每个模块只包含与其功能 ...
- 解决 vuex mapGetters 语法报错 (Unexpected token )
在使用vuex2的mapGetters 和 mapActions 的方法时,借助 stage2 的 Object Rest Operator 特性,可以写出下面代码: computed: { ... ...
- 结对项目:SudokuGame
1. Github项目地址:https://github.com/ZiJiaW/SudokuGame GUI在BIN目录下的SudokuGUI.rar中,解压后打开SudokuGame.exe即可.2 ...