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如上文中所述,满足(0

Output

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

Sample Input

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

Sample Output

96
93
96
 
 

我就是不用单调栈,你来打我啊~

线段树直接添加点和查询区间最大值,自己打的模板少了两个return居然没发现。。。捂脸熊。。。

题目似乎不好理解。。。看了好久才懂,然后发现自己是个傻逼。。。捂脸熊。。。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<algorithm>
  5 #include<cstring>
  6 #define MAX 200010
  7 using namespace std;
  8 int a[MAX];
  9 struct tree{
 10     int l,r,sum,lazy,maxx;
 11 }f[MAX*4];
 12 void pushup(int i){
 13     f[i].maxx=max(f[i*2+1].maxx,f[i*2].maxx);
 14     f[i].sum=f[i*2+1].sum+f[i*2].sum;
 15 }
 16 void update(int i,int x)
 17 {
 18     f[i].sum+=(f[i].r-f[i].l+1)*x;
 19     f[i].lazy+=x;
 20     f[i].maxx+=x;
 21 }
 22 void pushdown(int i){
 23 
 24     if(!f[i].lazy)return;
 25     update(i*2,f[i].lazy);
 26     update(i*2+1,f[i].lazy);
 27     f[i].lazy=0;
 28 }
 29 
 30 void build(int i,int left,int right){
 31     int mid=(left+right)/2;
 32     f[i].lazy=0;
 33     f[i].l=left;f[i].r=right;
 34     if(left==right){
 35         f[i].maxx=a[left];
 36         f[i].sum=a[left];
 37         return;
 38     }
 39     build(i*2,left,mid);
 40     build(i*2+1,mid+1,right);
 41     pushup(i);
 42 }
 43 
 44 void addmeg(int i,int left,int right,int v){
 45     int mid=(f[i].l+f[i].r)/2;
 46     if(f[i].l==left&&f[i].r==right){
 47         update(i,v);
 48         return;
 49     }
 50     pushdown(i);
 51     if(mid>=right)addmeg(i*2,left,right,v);    
 52     else if(mid<left)addmeg(i*2+1,left,right,v);
 53     else addmeg(i*2,left,mid,v),addmeg(i*2+1,mid+1,right,v);
 54     pushup(i);
 55 }
 56 int Max(int i,int left,int right){
 57     if(f[i].lazy==0){
 58         int mid=(f[i].l+f[i].r)/2;
 59         if(f[i].l==left&&f[i].r==right) return f[i].maxx;
 60         if(mid>=right) return Max(i*2,left,right);
 61         if(mid<left) return Max(i*2+1,left,right);
 62         return max(Max(i*2,left,mid),Max(i*2+1,mid+1,right));
 63     }
 64     if(f[i].lazy!=0){
 65         pushdown(i);
 66         return Max(i,left,right);
 67     }
 68 }
 69 
 70 int query(int i,int left, int right) {
 71     if(f[i].lazy==0){
 72         int mid=(f[i].l+f[i].r)/2;
 73         if(f[i].l==left&&f[i].r==right) return f[i].sum;
 74         if(mid>=right) return query(i*2,left,right);
 75         if(mid<left) return query(i*2+1,left,right);
 76         return query(i*2,left,mid)+query(i*2+1,mid+1,right);
 77     }
 78     if(f[i].lazy!=0){
 79         pushdown(i);
 80         return query(i,left,right);
 81     }
 82 }
 83 
 84 int main(){
 85     int n,d,last=0,ans=0;
 86     char b[10];
 87     scanf("%d%d",&n,&d);
 88     build(1,1,200010);
 89     for(int i=1,l;i<=n;i++){
 90         scanf("%s%d",b,&l);
 91         if(b[0]=='A'){
 92             ans++;
 93             addmeg(1,ans,ans,(l+last)%d);
 94         }
 95         else{
 96             last=Max(1,ans-l+1,ans);
 97             printf("%d\n",last);
 98         }
 99     }
100     return 0;
101 }
View Code

 

posted @ 2015-09-14 11:05  HTWX  阅读(107)  评论(0编辑  收藏  举报