BZOJ 1012 [JSOI2008] 最大数maxnumber(线段树水题)

 

题目大意

 

现在请求你维护一个数列,要求提供以下两种操作:

  1、 查询操作。

    语法:Q L

    功能:查询当前数列中末尾 L 个数中的最大的数,并输出这个数的值。

    限制:L 不超过当前数列的长度。

  2、 插入操作。

    语法:A n

    功能:将 n 加上 t,其中 t 是最近一次查询操作的答案(如果还未执行过查询操作,则 t=0),并将所得结果对一个固定的常数 D 取模,将所得答案插入到数列的末尾。

    限制:n 是非负整数并且在长整范围内。注意:初始时数列是空的,没有一个数。

 

Input

  第一行两个整数,M 和 D,其中 M 表示操作的个数(M<=200,000),D 如上文中所述

Output

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

 

做法分析

 

总算在这个 OJ 上找到一道非论文题的水题了...

用线段树离线搞,先统计出总共需要插入多少个数,这就是我们需要维护的线段树的大小

之后再从第一个操作开始模拟即可,维护两个东西:val 和 Max

 

参考代码

 

BZOJ 1012 [JSOI2008] 最大数maxnumber(线段树水题)
 1 #include <iostream>

 2 #include <cstring>

 3 #include <cstdio>

 4 

 5 using namespace std;

 6 

 7 const int N=200005;

 8 

 9 struct Segment_Tree {

10     struct Node {

11         int s, t, val, Max;

12         void init(int L, int R) {

13             s=L, t=R, val=Max=0;

14         }

15     } T[N<<2];

16 

17     void build(int id, int L, int R) {

18         T[id].init(L, R);

19         if(L==R) return;

20         int mid=(L+R)>>1;

21         build(id<<1, L, mid), build(id<<1|1, mid+1, R);

22     }

23 

24     void Insert(int id, int pos, int val) {

25         if(T[id].s==T[id].t) {

26             T[id].val=T[id].Max=val;

27             return;

28         }

29         int mid=(T[id].s+T[id].t)>>1;

30         if(pos<=mid) Insert(id<<1, pos, val);

31         else Insert(id<<1|1, pos, val);

32         T[id].Max=max(T[id<<1].Max, T[id<<1|1].Max);

33     }

34 

35     int query(int id, int L, int R) {

36         if(L<=T[id].s && T[id].t<=R) return T[id].Max;

37         int mid=(T[id].s+T[id].t)>>1;

38         if(R<=mid) return query(id<<1, L, R);

39         else if(L>mid) return query(id<<1|1, L, R);

40         else return max(query(id<<1, L, R), query(id<<1|1, L, R));

41     }

42 } tree;

43 

44 struct data {

45     char cmd[2];

46     int val;

47 } p[N];

48 int n, mod, tot;

49 

50 int main() {

51     scanf("%d%d", &n, &mod);

52     tot=0;

53     for(int i=0; i<n; i++) {

54         scanf("%s%d", p[i].cmd, &p[i].val);

55         if(p[i].cmd[0]=='A') tot++;

56     }

57     tree.build(1, 1, tot);

58     int R=0, last=0;

59     for(int i=0; i<n; i++) {

60         if(p[i].cmd[0]=='A') tree.Insert(1, ++R, (p[i].val+last)%mod);

61         else {

62             last=tree.query(1, R-p[i].val+1, R);

63             printf("%d\n", last);

64         }

65     }

66     return 0;

67 }
BZOJ 1012

 

题目链接 & AC 通道

 

BZOJ 1012 [JSOI2008] 最大数maxnumber

 

 

 

你可能感兴趣的:(number)