1012: [JSOI2008]最大数maxnumber

链接

 

思路:

  发现总的区间长度是不固定的,线段树是无法每次增加一个位置的,所以直接开始时默认区间长度是n(最多插入n个数),所以直接建线段树维护即可。

  另一种思路:维护一个单调栈,从上往下保证递增,并且记录栈中每个元素的位置,每次询问寻找栈中最靠下的,位置满足条件的元素。

 

代码

线段树:992ms

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<iostream>
 6 
 7 using namespace std;
 8 const int N = 800100;
 9 
10 int mx[N];
11 
12 #define lson l,mid,rt<<1
13 #define rson mid+1,r,rt<<1|1
14 void pushup(int rt) {
15     mx[rt] = max(mx[rt<<1],mx[rt<<1|1]);
16 }
17 void update(int l,int r,int rt,int p,int x) {
18     if (l==r) {
19         mx[rt] = x;
20         return ;
21     }
22     int mid = (l + r) / 2;
23     if (p <= mid) update(lson,p,x);
24     else update(rson,p,x);
25     pushup(rt);
26 }
27 int query(int l,int r,int rt,int L,int R) {
28     if (L <= l && r <= R) {
29         return mx[rt];
30     }
31     int mid = (l + r) / 2,ans = -1e9;
32     if (L <= mid) ans = max(ans,query(lson,L,R));
33     if (R > mid)  ans = max(ans,query(rson,L,R));
34     return ans;
35 }
36 int main () {
37     int n,D,a,ans = 0,cur = 0;
38     scanf("%d%d",&n,&D);
39     char s[10];
40     for (int i=1; i<=n; ++i) {
41         scanf("%s%d",s,&a);
42         if (s[0] == 'A') {
43             a = (a + ans) % D;
44             ++cur;
45             update(1,n,1,cur,a);
46         } else {
47             ans = query(1,n,1,cur-a+1,cur);
48             printf("%d\n",ans);
49         }
50     }
51     return 0;
52 }
View Code

 

单调栈:1752ms

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<iostream>
 6 
 7 using namespace std;
 8 const int N = 200100;
 9 
10 int st[N],top,pos[N];
11 
12 void Insert(int p,int x) {
13     while (x > st[top] && top >= 1) top--;
14     st[++top] = x;
15     pos[top] = p;
16 }
17 int Query(int p) {
18     int cur = top;
19     while (pos[cur] >= p) cur--;
20     return st[cur+1];
21 }
22 
23 int main () {
24     int n,D,a,ans = 0,cur = 0;
25     scanf("%d%d",&n,&D);
26     char s[10];
27     for (int i=1; i<=n; ++i) {
28         scanf("%s%d",s,&a);
29         if (s[0] == 'A') {
30             a = (a + ans) % D;
31             ++cur;
32             Insert(cur,a);
33         } else {
34             ans = Query(cur-a+1);
35             printf("%d\n",ans);
36         }
37     }
38     return 0;
39 }
View Code

 

posted @ 2018-04-10 21:50  MJT12044  阅读(148)  评论(0编辑  收藏  举报