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
A 96
Q 1
A 97
Q 1
Q 2
Sample Output
96
93
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 }