zoukankan      html  css  js  c++  java
  • 洛谷P1198 [JSOI2008]最大数(BZOJ.1012 )

    To 洛谷.1198 最大数

    题目描述

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

    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 100
    A 96
    Q 1
    A 97
    Q 1
    Q 2
    
    输出样例#1:
    96
    93
    96
    

    说明

    [JSOI2008]

     思路:

      1.线段树。在初始建树时将所有节点赋值为-INF,操作和单点修改与区间最值并没有多少不同。

      2.单调队列+二分查找。

    代码:

    1.线段树  722ms/17.06MB,比方法2要慢近一倍。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define LL long long
     4 using namespace std;
     5 const int N=200005,INF=1e9+10;
     6 
     7 int m,mod,len;
     8 LL t,Max[N<<2];
     9 
    10 void read(int &now)
    11 {
    12     now=0;bool f=0;char c=getchar();
    13     while(c<'0'||c>'9')
    14     {
    15         if(c=='-')f=1;
    16         c=getchar();
    17     }
    18     while(c>='0'&&c<='9')now=(now<<3)+(now<<1)+c-'0',c=getchar();
    19     now= f?-now:now;
    20 }
    21 
    22 void PushUp(int rt)
    23 {
    24     Max[rt]= Max[rt<<1]<Max[rt<<1|1]?Max[rt<<1|1]:Max[rt<<1];
    25 }
    26 
    27 void Build(int l,int r,int rt)
    28 {
    29     if(l==r)
    30     {
    31         Max[rt]=-INF;
    32         return;
    33     }
    34     int m=(l+r)>>1;
    35     Build(l,m,rt<<1);
    36     Build(m+1,r,rt<<1|1);
    37     PushUp(rt);
    38 }
    39 
    40 void ModifyPoint(int l,int r,int rt,int p,int v)
    41 {
    42     if(l==r)
    43     {
    44         Max[rt]= Max[rt]<v?v:Max[rt];
    45         return;
    46     }
    47     int m=(l+r)>>1;
    48     if(p<=m) ModifyPoint(l,m,rt<<1,p,v);
    49     else ModifyPoint(m+1,r,rt<<1|1,p,v);
    50     PushUp(rt);
    51 }
    52 
    53 LL QueryMax(int l,int r,int rt,int L,int R)
    54 {
    55     if(L<=l && r<=R) return Max[rt];
    56     int m=(l+r)>>1;
    57     LL res=-INF;
    58     if(L<=m) res=max(res,QueryMax(l,m,rt<<1,L,R));
    59     if(m<R) res=max(res,QueryMax(m+1,r,rt<<1|1,L,R));
    60     return res;
    61 }
    62 
    63 int main()
    64 {
    65     read(m);read(mod);
    66     Build(1,m,1);
    67     for(int i=1;i<=m;++i)
    68     {
    69         char opt[5];int num;
    70         scanf("%s",opt);read(num);
    71         if(opt[0]=='A')
    72           ModifyPoint(1,m,1,++len,(num+t)%mod);
    73         else
    74           printf("%lld
    ",t=QueryMax(1,m,1,len-num+1,len));
    75     }
    76     return 0;
    77 }
    线段树(插入元素 区间最值)

    2.单调队列+lower_bound(+栈) 337ms/12.6MB

    (先写 if(opt[0]=='Q')+询问 后写插入 就会错是什么鬼。。 哪位dalao看出来帮我指出一下。。thanks)

     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 const int N=200005;
     5 
     6 int m,mod,len,size,t,Num[N],Stack[N];
     7 
     8 void read(int &now)
     9 {
    10     now=0;bool f=0;char c=getchar();
    11     while(c<'0'||c>'9')
    12     {
    13         if(c=='-')f=1;
    14         c=getchar();
    15     }
    16     while(c>='0'&&c<='9')now=(now<<3)+(now<<1)+c-'0',c=getchar();
    17     now= f?-now:now;
    18 }
    19 
    20 /*int Mylower_bound(int s,int t,int p)
    21 {
    22     int l=s,r=t,m;
    23     while(l<r)
    24     {
    25         m=(l+r)>>1;
    26         if(Stack[m]<p)
    27           l=m+1;
    28         else if(Stack[m]==p)
    29           return m;
    30         else
    31           r=m;
    32     }
    33     return l;
    34 }*/
    35 
    36 int main()
    37 {
    38     read(m);read(mod);
    39     char opt[5];int a;
    40     while(m--)
    41     {
    42         scanf("%s",opt);read(a);
    43         if(opt[0]=='A')
    44         {//因为比当前元素小的数在最后的求最大值中毫无作用,所以直接弹出 
    45             a=(a+t)%mod;
    46             Num[++len]=a;
    47             while(size && Num[Stack[size]]<=a)
    48               --size;
    49             Stack[++size]=len;
    50         }
    51         else
    52         {//Stack[i]存储的是一个位置pos,且这些位置单调递增,这些位置对应的Num[pos]也单调递增 
    53             int pos=lower_bound(Stack+1,Stack+size+1,len-a+1)-Stack;//找出一个Stack中大于等于查询位置的pos 
    54             //int pos=Mylower_bound(1,size,len-a+1);
    55             printf("%d
    ",t=Num[Stack[pos]]);
    56         }
    57     }
    58     return 0;
    59 }
    单调队列

     错误的写法

     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 const int N=200005;
     5 
     6 int m,mod,len,size,t,Num[N],Stack[N];
     7 
     8 void read(int &now)
     9 {
    10     now=0;bool f=0;char c=getchar();
    11     while(c<'0'||c>'9')
    12     {
    13         if(c=='-')f=1;
    14         c=getchar();
    15     }
    16     while(c>='0'&&c<='9')now=(now<<3)+(now<<1)+c-'0',c=getchar();
    17     now= f?-now:now;
    18 }
    19 
    20 int main()
    21 {
    22     read(m);read(mod);
    23     char opt[5];int a;
    24     while(m--)
    25     {
    26         scanf("%s",opt);read(a);
    27         if(opt[0]=='Q')
    28         {//Stack[i]存储的是一个位置,且这些位置单调递增,这些位置对应的Num[pos]也单调递增 
    29             int pos=lower_bound(Stack+1,Stack+size+1,len-a+1)-Stack;
    30             printf("%d
    ",t=Num[pos]);
    31         }
    32         else
    33         {//因为比当前元素小的数在最后的求最大值中毫无作用,所以直接弹出 
    34             a=(a+t)%mod;
    35             Num[++len]=a;
    36             while(size && Num[Stack[size]]<=a)
    37               --size;
    38             Stack[++size]=len;
    39         }
    40     }
    41     return 0;
    42 }
    0分
  • 相关阅读:
    题解:luoguP1070 道路游戏(DP)
    题解:luoguP2577【ZJOI2005】午餐(DP)
    题解:bzoj1801: [Ahoi2009]chess 中国象棋
    题解:bzoj1878: [SDOI2009]HH的项链
    SpringBoot静态资源文件 lion
    简要的Log4Net 应用配置
    Web Service 初级教程
    log4Net 动态改变写入文件
    Ornament 类型资源权限
    JQuery 引发两次$(document).ready事件
  • 原文地址:https://www.cnblogs.com/SovietPower/p/6895648.html
Copyright © 2011-2022 走看看