博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[JSOI2008]最大数
阅读量:5235 次
发布时间:2019-06-14

本文共 2869 字,大约阅读时间需要 9 分钟。

题目描述

现在请求你维护一个数列,要求提供以下两种操作:

1、 查询操作。

语法:Q L

功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值。

限制:L不超过当前数列的长度。

2、 插入操作。

语法:A n

功能:将n加上t,其中t是最近一次查询操作的答案(如果还未执行过查询操作,则t=0),并将所得结果对一个固定的常数D取模,将所得答案插入到数列的末尾。

限制:n是整数(可能为负数)并且在长整范围内。

注意:初始时数列是空的,没有一个数。

输入输出格式

输入格式:

第一行两个整数,M和D,其中M表示操作的个数(M <= 200,000),D如上文中所述,满足(0<D<2,000,000,000)

接下来的M行,每行一个字符串,描述一个具体的操作。语法如上文所述。

输出格式:

对于每一个查询操作,你应该按照顺序依次输出结果,每个结果占一行。

输入输出样例

输入样例#1:
5 100A 96Q 1A 97Q 1Q 2
输出样例#1:
969396
题解:

运用线段树的算法。

这道题看似长度是变化的,其实可以转化

直接将序列看做1~m的数列,将数一个一个加入,并记录当前位置就行了

首先建树,把所有的节点的值赋成min_int。用[i,j]表示该区间的最大值。

1)读入Q L操作。用len表示区间的大小,在len+1的位置放入(L+T)%D的值。

2)读入A n操作。输出区间[len-n+1,len]这个区间中的最大值,并把t的值进行更新。

此题还可以用二分和单调栈

 

1 #include
2 #include
3 #include
4 using namespace std; 5 int M,D,t=0; 6 int size; 7 int a[200500]; 8 int num[200500]; 9 int main() 10 { 11 int Ln,len=0; 12 char QA[5]; 13 scanf("%d%d", &M, &D); 14 while(M--) 15 { 16 scanf("%s %d", QA, &Ln); 17 if(QA[0] == 'A')//查询操作 18 { 19 Ln=(Ln+t)%D; 20 num[++len]=Ln;//每次加入一个Ln,num数组长度++ 21 while(size&&num[a[size]]<=Ln) 22 size--;//单调栈操作 23 a[++size]=len; 24 } 25 else //插入操作 26 { 27 int pos=lower_bound(a+1,a+size+1,len-Ln+1)-a; //二分查找 28 t=num[a[pos]]; 29 cout<
<

 

线段树

 

1 #include
2 #include
3 #include
4 using namespace std; 5 int c[800001],ans; 6 void add(int rt,int l,int r,int p,int k) 7 { 8 if (l==r) 9 {10 c[rt]=k;11 return;12 }13 int mid=(l+r)>>1;14 if (p<=mid) add(rt<<1,l,mid,p,k);15 else add(rt<<1|1,mid+1,r,p,k);16 c[rt]=max(c[rt<<1],c[rt<<1|1]);17 }18 int query(int rt,int l,int r,int L,int R)19 {20 if (l>=L&&r<=R)21 {22 return c[rt];23 }24 int mid=(l+r)>>1,s=-2147283647;25 if (L<=mid) s=max(s,query(rt<<1,l,mid,L,R));26 if (R>mid) s=max(s,query(rt<<1|1,mid+1,r,L,R));27 return s;28 }29 void build(int rt,int l,int r)30 {31 c[rt]=-2147283647;32 if (l==r)return;33 int mid=(l+r)>>1;34 build(rt<<1,l,mid);build(rt<<1|1,mid+1,r);35 }36 int main()37 {
int n;38 char ch;39 int m,d,t,i,l;40 cin>>m>>d;41 t=0;42 int x=0;43 build(1,1,m);44 for (i=1;i<=m;i++)45 {46 cin>>ch;47 if (ch=='A')48 {49 scanf("%d",&n);50 n=(n+t)%d;51 x++;52 add(1,1,m,x,n);53 }54 else 55 {56 scanf("%d",&l);57 ans=query(1,1,m,x-l+1,x);58 t=ans;59 printf("%d\n",ans);60 }61 }62 }

转载于:https://www.cnblogs.com/Y-E-T-I/p/7122523.html

你可能感兴趣的文章
POJ 3278 Catch That Cow BFS
查看>>
bzoj1193:马步距离
查看>>
jQuery live()方法使用及变更(事件委托)
查看>>
Java类载入器(一)——类载入器层次与模型
查看>>
How To run OAI eNB (No S1) with USRP X310(1)
查看>>
html标签
查看>>
洛谷 [P1995] 程序自动分析
查看>>
jQuery.on() 函数详解
查看>>
中文词频统计
查看>>
羊车问题
查看>>
想要什么适配什么?
查看>>
jQuery_5AJAX使用
查看>>
redis 开启远程访问权限
查看>>
马克鳗
查看>>
[CodeVs3196]黄金宝藏(DP/极大极小搜索)
查看>>
C# 怎么让winform程序中的输入文本框保留上次的输入
查看>>
上周热点回顾(5.25-5.31)
查看>>
canvas标签画布实际宽高与显示在界面中宽高的区别
查看>>
SpringBoot中常用注解@Controller/@RestController/@RequestMapping的区别
查看>>
ASP.NET Core 依赖注入(DI)
查看>>