题目链接:

https://www.luogu.org/problemnew/show/P1198

题目描述

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

1、 查询操作。

语法:Q L

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

限制:LL不超过当前数列的长度。(L > 0)(L>0)

2、 插入操作。

语法:A n

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

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

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

输入输出格式

输入格式:

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

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

输出格式:

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

输入输出样例

输入样例#1: 复制

  1. 5 100
  2. A 96
  3. Q 1
  4. A 97
  5. Q 1
  6. Q 2
输出样例#1: 复制

  1. 96
  2. 93
  3. 96

单调栈解法。因为题目求的是末尾L个数的最大值,利用两个栈分别存储最大值和最大值的位置。然后二分查找。注意二分查找时上界是总得个数减去区间长度,而不是栈的空间减去区间长度,因为不符合栈的数值已经出栈了。

单调栈解法参考自:https://www.luogu.org/blog/user38348/solution-p1198

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #define ll long long
  5. using namespace std;
  6. long long Stack[2][200010];
  7. long long cnt=0,top=0;
  8. void add(long long val){
  9. cnt++;
  10. while(Stack[0][top]<val&&(top>0)) top--;
  11. Stack[0][++top]=val;
  12. Stack[1][top]=cnt;
  13. }
  14. long long quiry(long long L){
  15. int l=1,r=top;
  16. int ind=cnt-L+1;
  17. // int ind=top-L+1;
  18. while(l<r){
  19. int mid=(l+r)>>1;
  20. if(Stack[1][mid]<ind) l=mid+1;
  21. else r=mid;
  22. }
  23. return Stack[0][l];
  24. }
  25. int main(int argc, char** argv) {
  26. int M;long long D;
  27. scanf("%d %lld",&M,&D);
  28. long long t=0;
  29. while(M--){
  30. char c;
  31. long long d;
  32. cin>>c>>d;
  33. if(c=='A'){
  34. add((t+d)%D);
  35. }
  36. else if(c=='Q'){
  37. t=quiry(d);
  38. printf("%lld\n",t);
  39. }
  40. }
  41. return 0;
  42. }

线段树解法,维护区间的最大值。

  1. #include <iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #define ll long long
  5. using namespace std;
  6. const int maxn=200010*4;
  7. ll Max[maxn];
  8.  
  9. void add(int p,int l,int r,int x,ll c){
  10. if(l==r){
  11. Max[p]=c;return;
  12. }
  13. int mid=(l+r)>>1;
  14. if(x<=mid) add(p<<1,l,mid,x,c);
  15. else add(p<<1|1,mid+1,r,x,c);
  16. Max[p]=max(Max[p<<1],Max[p<<1|1]);
  17. }
  18. int quiry(int p,int l,int r,int a,int b){
  19. if(a>r||b<l) return -1e8;
  20. if(a<=l&&r<=b){
  21. return Max[p];
  22. }
  23. int mid=(l+r)>>1;
  24. return max(quiry(p<<1,l,mid,a,b),quiry(p<<1|1,mid+1,r,a,b));
  25. }
  26. int main(int argc, char** argv) {
  27. int M,D;
  28. scanf("%d %d",&M,&D);
  29. fill(Max,Max+maxn,-1e8);
  30. ll t=0;
  31. int x=0;
  32. while(M--){
  33. char c;int d;
  34. cin>>c>>d;
  35. if(c=='A'){
  36. x++;
  37. ll num=(t+d)%D;
  38. add(1,1,200010,x,num);
  39. }else if(c=='Q'){
  40. t=quiry(1,1,200010,x-d+1,x);
  41. printf("%lld\n",t);
  42. }
  43. }
  44. return 0;
  45. }

洛谷P1198 [JSOI2008]最大数(线段树/单调栈)的更多相关文章

  1. 「线段树」「单点修改」洛谷P1198 [JSOI2008]最大数

    「线段树」「单点修改」洛谷P1198 [JSOI2008]最大数 题面描述 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数, ...

  2. 洛谷 P1198 [JSOI2008]最大数

    洛谷 P1198 [JSOI2008]最大数 题目描述 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值. ...

  3. 洛谷P1198 [JSOI2008]最大数(单点修改,区间查询)

    洛谷P1198 [JSOI2008]最大数 简单的线段树单点问题. 问题:读入A和Q时,按照读入一个字符会MLE,换成读入字符串就可以了. #include<bits/stdc++.h> ...

  4. 【题解】洛谷P1198 [JSOI2008] 最大数(线段树)

    洛谷P1198:https://www.luogu.org/problemnew/show/P1198 思路 一道水水的线段树 20分钟A掉 这道题只涉及到单点修改和区间查询 所以这道题甚至不用Laz ...

  5. 洛谷P1198 [JSOI2008]最大数

    P1198 [JSOI2008]最大数 267通过 1.2K提交 题目提供者该用户不存在 标签线段树各省省选 难度提高+/省选- 提交该题 讨论 题解 记录 最新讨论 WA80的戳这QwQ BZOJ都 ...

  6. 洛谷 P1198 [JSOI2008]最大数——单调栈/线段树

    先上一波题目 https://www.luogu.org/problem/P1198 题目要求维护后缀最大值 以及在数列的最后面添加一个数 这道题呢我们有两种做法 1.单调栈 因为只需要维护后缀最大值 ...

  7. 洛谷P1198 [JSOI2008]最大数(线段树)

    题目描述 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值. 限制:LLL不超过当前数列的长度.(L> ...

  8. 洛谷P1198 [JSOI2008]最大数(BZOJ.1012 )

    To 洛谷.1198 最大数 题目描述 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值. 限制:L不超过当 ...

  9. BZOJ——1012: [JSOI2008]最大数maxnumber || 洛谷—— P1198 [JSOI2008]最大数

    http://www.lydsy.com/JudgeOnline/problem.php?id=1012|| https://www.luogu.org/problem/show?pid=1198 T ...

随机推荐

  1. iOS10 App适配权限 Push Notifications 字体Frame 遇到的坑!!!!

    添加配置权限 <!-- 相册 --> <key>NSPhotoLibraryUsageDescription</key> <string>"x ...

  2. 牛客挑战赛46 B

    题目链接: 最小的指数 乍一看还以为是Pollard_rho算法,其实大可不必. 发现\(1<= n <= 1e18\),我们可以将n分为两部分(分块思想降低时间复杂度). 剔除小于等于\ ...

  3. 一文搞懂Java引用拷贝、浅拷贝、深拷贝

    微信搜一搜 「bigsai」 专注于Java和数据结构与算法的铁铁 文章收录在github/bigsai-algorithm 在开发.刷题.面试中,我们可能会遇到将一个对象的属性赋值到另一个对象的情况 ...

  4. [RoarCTF 2019]Easy Calc

    [RoarCTF 2019]Easy Calc 题目 题目打开是这样的 查看源码 .ajax是指通过http请求加载远程数据. 可以发现有一个calc.php,输入的算式会被传入到这个php文件里,尝 ...

  5. sqoop用法之mysql与hive数据导入导出

    目录 一. Sqoop介绍 二. Mysql 数据导入到 Hive 三. Hive数据导入到Mysql 四. mysql数据增量导入hive 1. 基于递增列Append导入 1). 创建hive表 ...

  6. javascript笔记day01

    JavaScript基础语法 HTML :标记语言 JavaScript :编程语言 序言 JavaScript发展历史(JS) 1. 1994年,网景公司(Netscape)发布了Navigator ...

  7. Python循环语句代码详解:while、for、break

    1 while循环 循环语句是程序设计中常用的语句之一.任何编程语言都有while循环,Python也不例外.while循环的格式如下所示.  while(表达式):       -   else:  ...

  8. JVM 经典垃圾收集器

    本文部分摘自<深入理解 Java 虚拟机第三版> 概述 如果说收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的实践者.Java 虚拟机规范中对垃圾收集器的实现做出规定,因此不同的厂 ...

  9. Linux内核源码分析之setup_arch (三)

    1. 前言 在 Linux内核源码分析之setup_arch (二) 中介绍了当前启动阶段的内存分配函数memblock_alloc,该内存分配函数在本篇将要介绍paging_init中用于页表和内存 ...

  10. Java IO流 FileOutputStream、FileInputStream的用法   

    FileOutputStream.FileInputStream的使用 FileOutputStream是OutputStream的继承类,它的主要功能就是向磁盘上写文件.FileOutputStre ...