很裸的线段树 ||
单调队列:
如果一个节点在队列中既没有时间优势(早点入队)也没有值优势(值更大),那么显然无论在怎样的情况下都不会被选为最大值。
既然它只在末尾选,那么自然可以满足以上的条件。
线段树
#include "stdio.h"
#include "string.h"
struct node
{
int l,r,Max;
}data[800010];
int Max(int a,int b)
{
if (a<b) return b;
else return a;
}
void build(int l,int r,int k)
{
int mid;
data[k].l=l;
data[k].r=r;
data[k].Max=0;
if (l==r) return ;
mid=(l+r)/2;
build(l,mid,k*2);
build(mid+1,r,k*2+1);
}
void updata(int w,int k,int op)
{
int mid;
if (data[k].l==w && data[k].r==w)
{
data[k].Max=op;
return ;
}
mid=(data[k].l+data[k].r)/2;
if (w<=mid) updata(w,k*2,op);
else updata(w,k*2+1,op);
data[k].Max=Max(data[k*2].Max,data[k*2+1].Max);
}
int query(int l,int r,int k)
{
int mid;
if (data[k].l==l && data[k].r==r)
return data[k].Max;
mid=(data[k].l+data[k].r)/2;
if (r<=mid) return query(l,r,k*2);
else if (l>mid) return query(l,r,k*2+1);
else return Max(query(l,mid,k*2),query(mid+1,r,k*2+1));
}
int main()
{
int m,d,t,x,now;
char ch[2];
while (scanf("%d%d",&m,&d)!=EOF)
{
build(1,m,1);
t=0;
now=0;
while (m--)
{
scanf("%s%d",ch,&x);
if (ch[0]=='A')
{
x=(x+t)%d;
now++;
updata(now,1,x);
}else
{
t=query(now-x+1,now,1);
printf("%d\n",t);
}
}
}
return 0;
}
单调队列:
#include "stdio.h"
#include "string.h"
int f[200010];
int main()
{
int t,now,m,d,x,i;
char ch[2];
while (scanf("%d%d",&m,&d)!=EOF)
{
t=0;
now=0;
while (m--)
{
scanf("%s%d",ch,&x);
if (ch[0]=='A')
{
f[++now]=(x+t)%d;
for (i=now-1;i>=1;i--)
if (f[i]<f[now]) f[i]=f[now];
else break;
}
else
printf("%d\n",t=f[now-x+1]);
}
}
return 0;
}