BZOJ1012 [JSOI2008] 最大数maxnumber

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

Description

现在请求你维护一个数列,要求提供以下两种操作: 1、 查询操作。语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值。限制:L不超过当前数列的长度。 2、 插入操作。语法:A n 功能:将n加上t,其中t是最近一次查询操作的答案(如果还未执行过查询操作,则t=0),并将所得结果对一个固定的常数D取模,将所得答案插入到数列的末尾。限制:n是非负整数并且在长整范围内。注意:初始时数列是空的,没有一个数。

乍一看动态开点的线段树?其实不需要动态开点,只是“插入到数列的末尾”而不是插入到中间哪个地方,把所有的点开好,记录下当前数列的长度,在数列的末端线段树单点修改就行了。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 #define rep(i,l,r) for(int i=l; i<=r; i++)
 6 #define clr(x,y) memset(x,y,sizeof(x))
 7 #define travel(x) for(int i=last[x]; i; i=edge[i].pre)
 8 using namespace std;
 9 const int INF = 0x3f3f3f3f;
10 const int maxn = 200010;
11 struct node{
12     int l,r,mx;
13 }t[maxn<<2];
14 int m,KPM,x,last,cnt=0;
15 char ch;
16 inline int read(){
17     int ans = 0, f = 1;
18     char c = getchar();
19     while (!isdigit(c)){
20         if (c == '-') f = -1;
21         c = getchar();
22     }
23     while (isdigit(c)){
24         ans = ans * 10 + c - '0';
25         c = getchar();
26     }
27     return ans * f;
28 }
29 void build(int u,int v,int w){
30     t[w].l = u; t[w].r = v; t[w].mx = -INF;
31     if (u == v) return;
32     int mid = (u + v) >> 1;
33     build(u,mid,w<<1);
34     build(mid+1,v,w<<1|1);
35 }
36 void insert(int u,int w,int x){
37     if (t[w].l == t[w].r){
38         t[w].mx = x; return;
39     }
40     int mid = (t[w].l + t[w].r) >> 1;
41     if (u <= mid) insert(u,w<<1,x);
42     else insert(u,w<<1|1,x);
43     t[w].mx = max(t[w<<1].mx,t[w<<1|1].mx);
44 }
45 int query(int u,int v,int w){
46     if (u == t[w].l && v == t[w].r) return t[w].mx;
47     int mid = (t[w].l + t[w].r) >> 1;
48     if (v <= mid) return query(u,v,w<<1);
49     else if (u > mid) return query(u,v,w<<1|1);
50     else return max(query(u,mid,w<<1),query(mid+1,v,w<<1|1));
51 }
52 int main(){
53     m = read(); KPM = read();
54     build(1,m,1);
55     rep(i,1,m){
56         scanf("%c",&ch);
57         switch(ch){
58             case 'Q':
59                 x = read();
60                 last = query(cnt-x+1,cnt,1);
61                 printf("%d\n",last);
62             break;
63             case 'A':
64                 x = read(); cnt++;
65                 x = (x + last) % KPM;
66                 insert(cnt,1,x);
67             break;
68         }
69     }
70     return 0;
71 }
View Code

 

posted on 2015-11-28 18:22  ACMICPC  阅读(230)  评论(0编辑  收藏  举报

导航