第一眼看到这题大家都觉得是一道线段树的水题,然而它却是一道暴力完美解决的超级大水题。估计难度在NOIP pj第一题左右… …
去看了看数据…没什么感觉……
再看看别人的代码长度…
这一定不是线段树!!!!
也有人考虑用单调队列或单调栈来做,那样的话代码也很短,而且时间也可过(可怜的数据)…重点是如果把这题放在NOIP上,AC率一定非常高。签到题一样的…
不说了,直接看代码吧…
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=200005;
int M,D,x,t=0;
int a[N],b[N];
char cym[3];
int main()
{
memset (b,-1,sizeof(b));
scanf ("%d%d",&M,&D);
int j=1;
for (int i=1;i<=M;i++)
{
scanf ("%s%d",cym,&x);
if (cym[0]=='A')
{
int y=(x+t)%D;
a[j++]=y;
for (int k=j;k>=1;k--)
{
if (y>b[k])
b[k]=y;
else
break; //就是这个跳出循环,凸显了数据之弱...
}
}
else
{
t=b[j-x+1];
printf ("%d\n",t);
}
}
return 0;
}
如果你是JSOI2008的参赛选手,你敢这样写么…果断选择线段树啊… …
附:%%%%%%进队CYM%%%%%%%%%%
http://blog.csdn.net/cym19981017
#include<iostream>
#include<cstdio>
using namespace std;
int M,D,last,cnt;
struct data
{
int l,r,mx;
}t[800005];
void build(int idx,int l,int r)
{
t[idx].l=l;
t[idx].r=r;
t[idx].mx=-1;
if(l==r)
return;
int mid=(l+r)>>1;
build(idx<<1,l,mid);
build(idx<<1|1,mid+1,r);
}
inline int Query(int idx,int l,int r)
{
if (t[idx].l==l&&t[idx].r==r)
return t[idx].mx;
int mid=(t[idx].l+t[idx].r)>>1;
if (r<=mid)
return Query(idx<<1,l,r);
else if (l>mid)
return Query(idx<<1|1,l,r);
else
return max(Query(idx<<1,l,mid),Query(idx<<1|1,mid+1,r));
}
inline void insert (int idx,int i,int x)
{
if(t[idx].l==t[idx].r)
{
t[idx].mx=x;
return;
}
int mid=(t[idx].l+t[idx].r)>>1;
if (i<=mid)
insert (idx<<1,i,x);
else
insert (idx<<1|1,i,x);
t[idx].mx=max(t[idx<<1].mx,t[idx<<1|1].mx);
}
int main()
{
scanf ("%d%d",&M,&D);
build(1,1,M);
int t=0;
int j=0,x;
for (int i=1;i<=M;i++)
{
char cym[5];
scanf ("%s",cym);
if(cym[0]=='A')
{
scanf ("%d",&x);
j++;
x=(x+t)%D;
insert(1,j,x);
}
else
{
scanf ("%d",&x);
t=Query(1,j-x+1,j);
printf("%d\n",t);
}
}
return 0;
}