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 }

 

posted @ 2015-04-04 22:33  huangxf  阅读(163)  评论(0编辑  收藏  举报