【bzoj 1012】 最大数maxnumber 【JSOI2008】

Description

  现在请求你维护一个数列,要求提供以下两种操作:1、 查询操作。语法:Q L 功能:查询当前数列中末尾L
个数中的最大的数,并输出这个数的值。限制:L不超过当前数列的长度。2、 插入操作。语法:A n 功能:将n加
上t,其中t是最近一次查询操作的答案(如果还未执行过查询操作,则t=0),并将所得结果对一个固定的常数D取
模,将所得答案插入到数列的末尾。限制:n是非负整数并且在长整范围内。注意:初始时数列是空的,没有一个
数。

Input

  第一行两个整数,M和D,其中M表示操作的个数(M <= 200,000),D如上文中所述,满足D在longint内。接下来
M行,查询操作或者插入操作。

Output

  对于每一个询问操作,输出一行。该行只有一个数,即序列中最后L个数的最大数。

Sample Input

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

Sample Output

96
93
96

这道题可以用线段树或者单调队列,下面是程序:

线段树:

[cpp]  view plain  copy
  1. #include<stdio.h>  
  2. #include<iostream>  
  3. using namespace std;  
  4. const int N=800005;  
  5. struct tree{  
  6.     int lc,rc,key;  
  7. }t[N];  
  8. int k;  
  9. void build(int rt,int l,int r){  
  10.     if(l==r){  
  11.         t[rt].key=t[rt].lc=t[rt].rc=0;  
  12.         return;  
  13.     }  
  14.     int m=(l+r)>>1;  
  15.     t[rt].lc=++k;  
  16.     t[rt].rc=++k;  
  17.     build(t[rt].lc,l,m);  
  18.     build(t[rt].rc,m+1,r);  
  19.     t[rt].key=max(t[t[rt].lc].key,t[t[rt].rc].key);  
  20. }  
  21. void add(int rt,int l,int r,int k,int w){  
  22.     if(l==r&&l==k){  
  23.         t[rt].key=w;  
  24.         return;  
  25.     }  
  26.     int m=(l+r)>>1;  
  27.     if(k<=m){  
  28.         add(t[rt].lc,l,m,k,w);  
  29.     }  
  30.     else{  
  31.         add(t[rt].rc,m+1,r,k,w);  
  32.     }  
  33.     t[rt].key=max(t[t[rt].lc].key,t[t[rt].rc].key);  
  34. }  
  35. int ask(int rt,int l,int r,int a,int b){  
  36.     if(l==a&&r==b){  
  37.         return t[rt].key;  
  38.     }  
  39.     int m=(l+r)>>1;  
  40.     if(b<=m){  
  41.         return ask(t[rt].lc,l,m,a,b);  
  42.     }  
  43.     if(a>m){  
  44.         return ask(t[rt].rc,m+1,r,a,b);  
  45.     }  
  46.     return max(ask(t[rt].lc,l,m,a,m),ask(t[rt].rc,m+1,r,m+1,b));  
  47. }  
  48. void read(int &s){  
  49.     s=0;  
  50.     int f=1;  
  51.     char c=getchar();  
  52.     while((c<'0'||c>'9')&&c!='-'){  
  53.         c=getchar();  
  54.     }  
  55.     if(c=='-'){  
  56.         f=-1;  
  57.         c=getchar();  
  58.     }  
  59.     while(c>='0'&&c<='9'){  
  60.         s*=10;  
  61.         s+=c-'0';  
  62.         c=getchar();  
  63.     }  
  64.     s*=f;  
  65. }  
  66. void ch(char &c){  
  67.     c=getchar();  
  68.     while(c!='A'&&c!='Q'){  
  69.         c=getchar();  
  70.     }  
  71. }  
  72. int main(){  
  73.     int n,mod,q=0,x,l=0,i;  
  74.     char c;  
  75.     read(n);  
  76.     read(mod);  
  77.     build(0,1,n);  
  78.     for(i=0;i<n;i++){  
  79.         ch(c);  
  80.         read(x);  
  81.         if(c=='A'){  
  82.             add(0,1,n,++l,(q+x)%mod);  
  83.         }  
  84.         else{  
  85.             printf("%d\n",q=ask(0,1,n,l-x+1,l));  
  86.         }  
  87.     }  
  88.     return 0;  
  89. }  

传送门

猜你喜欢

转载自blog.csdn.net/jialiang2509/article/details/80040759