BZOJ 1012: [JSOI2008]最大数maxnumber 线段树

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1012

现在请求你维护一个数列,要求提供以下两种操作: 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

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

算法分析:起初咋一看,可以用线段树做,于是就做了,迅速搞之,交之,WA...,为啥了,不应该呀,查代码,又交之,WA,,,无语中,后来突然想起了,C++提交得用lld呀,平常习惯了I64d了,买了个表的。

不过这道题可以用单调栈做,而且代码比线段树更简单。

 1 #include<iostream>

 2 #include<cstdio>

 3 #include<cstring>

 4 #include<cstdlib>

 5 #include<cmath>

 6 #include<algorithm>

 7 #define inf 0x7fffffff

 8 using namespace std;

 9 typedef long long LL;

10 const int maxn=200000+10;

11 

12 LL M,D;

13 LL cnt,an[maxn],sum[maxn<<2];

14 

15 void PushUP(LL rt) {sum[rt]=max(sum[rt<<1],sum[rt<<1|1]); }

16 

17 void build(LL l,LL r,LL rt)

18 {

19     sum[rt]=-inf;

20     if (l==r) return;

21     LL mid=(l+r)>>1;

22     build(l,mid,rt<<1);

23     build(mid+1,r,rt<<1|1);

24     PushUP(rt);

25 }

26 

27 void update(LL l,LL r,LL rt,LL p,LL value)

28 {

29     if (l==r) {sum[rt]=value;return; }

30     LL mid=(l+r)>>1;

31     if (p<=mid) update(l,mid,rt<<1,p,value);

32     else update(mid+1,r,rt<<1|1,p,value);

33     PushUP(rt);

34 }

35 

36 LL query(LL l,LL r,LL rt,LL x,LL y)

37 {

38     if (x<=l && r<=y) return sum[rt];

39     LL mid=(l+r)>>1;

40     LL ret=-inf;

41     if (y<=mid) ret=max(ret,query(l,mid,rt<<1,x,y));

42     else if (x>mid) ret=max(ret,query(mid+1,r,rt<<1|1,x,y));

43     else

44     {

45         ret=max(ret,query(l,mid,rt<<1,x,y));

46         ret=max(ret,query(mid+1,r,rt<<1|1,x,y));

47     }

48     PushUP(rt);

49     return ret;

50 }

51 

52 int main()

53 {

54     while (scanf("%lld%lld",&M,&D)!=EOF)

55     {

56         memset(sum,0,sizeof(sum));

57         LL t=0,N=M;

58         char ch[3];

59         LL l,v;

60         cnt=0;

61         build(1,M,1);

62         for (LL i=0 ;i<M ;i++)

63         {

64             scanf("%s",ch);

65             if (ch[0]=='A')

66             {

67                 scanf("%lld",&v);

68                 v=(v+t)%D;

69                 update(1,N,1,++cnt,v);

70             }

71             else

72             {

73                 scanf("%lld",&l);

74                 LL ans=query(1,N,1,cnt-l+1,cnt);

75                 printf("%lld\n",ans);

76                 t=ans;

77             }

78         }

79     }

80     return 0;

81 }

 

你可能感兴趣的:(number)