• [JSOI2008]最大数maxnumber


    1012: [JSOI2008]最大数maxnumber

    Time Limit: 3 Sec  Memory Limit: 162 MB
    Submit: 5667  Solved: 2461
    [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

    5 100
    A 96
    Q 1
    A 97
    Q 1
    Q 2

    Sample Output

    96
    93
    96

    HINT

     

    Source

                               [Submit][Status][Discuss]

     
      1.单调队列,比较好理解,就是如果要新加入的数比前面若干个数大,就把这若干个数覆盖掉,通俗点说,又靠后值又大的数比较diao,因为撑死20w个数,所以开两个20w的数组就够了。
      我们平时写单调队列时,貌似比较多的是用两个指针head,tail来维护队列Q[]数组,但这题貌似行不通,因为每次询问的L不固定,不能舍弃数列的任意一部分,所以用了“覆盖”的方法。

      注意:在输入字符A或Q时,如果像我下面那样定义ch[5],用 cin>>ch 是错的,要用scanf("%s",ch); 否则会RE,我也不知道为啥

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 int Q[200005];
     6 int a[200005];
     7 char ch[5];
     8 int L,N,T,D,M,tot;
     9 inline void workA();
    10 inline void workQ();
    11 int main(){
    12     cin>>M>>D;
    13     for(int i=1;i<=M;i++){
    14         scanf("%s",ch);
    15         //cin>>ch;//RE的 
    16         if(ch[0]=='A')
    17             workA();
    18         else
    19             workQ();
    20     }
    21     return 0;
    22 }
    23 inline void workA(){
    24     scanf("%d",&N);
    25     a[++tot]=(T+N)%D;
    26     for(int i=tot;i;i--){
    27         if(Q[i]<a[tot])
    28            Q[i]=a[tot];
    29         else break;
    30     }
    31 }
    32 inline void workQ(){
    33     scanf("%d",&L);
    34     printf("%d
    ",T=Q[tot-L+1]);
    35 }

      

      2.用线段树,相比之下太长了,还容易错,就不分析了,网上随便整的一个代码

      

     1 #include<iostream>
     2 #include<cstdio>
     3 #define inf 0x7fffffff
     4 using namespace std;
     5 int m,mod,last,cnt;
     6 struct data{int l,r,mx;}t[800005];
     7 void build(int k,int l,int r)
     8 {
     9     t[k].l=l;t[k].r=r;t[k].mx=-inf;
    10     if(l==r)return;
    11     int mid=(l+r)>>1;
    12     build(k<<1,l,mid);
    13     build(k<<1|1,mid+1,r);
    14 }
    15 int ask(int k,int x,int y)
    16 {
    17     int l=t[k].l,r=t[k].r;
    18     if(l==x&&r==y)return t[k].mx;
    19     int mid=(l+r)>>1;
    20     if(y<=mid)return ask(k<<1,x,y);
    21     else if(x>mid)return ask(k<<1|1,x,y);
    22     else return max(ask(k<<1,x,mid),ask(k<<1|1,mid+1,y));
    23 }
    24 void insert(int k,int x,int y)
    25 {
    26     int l=t[k].l,r=t[k].r;
    27     if(l==r){t[k].mx=y;return;}
    28     int mid=(l+r)>>1;
    29     if(x<=mid)insert(k<<1,x,y);
    30     else insert(k<<1|1,x,y);
    31     t[k].mx=max(t[k<<1].mx,t[k<<1|1].mx);
    32 }
    33 int main()
    34 {
    35     scanf("%d%d",&m,&mod);
    36     build(1,1,m);
    37     for(int i=1;i<=m;i++)
    38     {
    39         char ch[5];scanf("%s",ch);
    40         int x;
    41         if(ch[0]=='A')
    42         {
    43             cnt++;
    44             scanf("%d",&x);x=(x+last)%mod;
    45             insert(1,cnt,x);
    46         }
    47         else 
    48         {
    49             scanf("%d",&x);
    50             last=ask(1,cnt-x+1,cnt);
    51             printf("%d
    ",last);
    52         }
    53     }
    54     return 0;
    55 }
     
  • 相关阅读:
    修改 MySQL 的 sql_mode 模式方法
    PHP 实现 Redis 连接池
    【转载】php解决高并发问题
    PHP 7 不适用函数:password_hash
    PDO 防止 SQL 注入示例
    记录一次 header 参数格式引发的错误
    Laravel 框架数据库查询构造器中 when 的易犯错误
    PHP 7.3.4 安装 Redis 4.0(Windows系统)
    汇编语言全梳理(精简版)
    Anaconda安装和使用
  • 原文地址:https://www.cnblogs.com/CXCXCXC/p/4680756.html
Copyright © 2020-2023  润新知