bzoj 1012

Bzoj 1012 [jsoi2008]最大数maxnumber

题目大意:维护一个队列,每次往队尾加一个数或者一个询问(末尾的l个数中的最大值是多少)

解:我是用树状数组维护最大值,我沙茶地把lowbit(x)-1写成了lowbit(x-1),wa了若干次还以为是自己写错了。本题线段树亦可,然后还有一种单调队列+并茶几的算法,这个可用于离线的rmq问题,复杂度O(n),下面分段说。

 

因为这个队列只会往后增加而不会减小,有一个单调队列的性质(维护单调递减),f[i]表示从第i个数到末尾的最大的数的下标,然后不断把这些最小的数连向他后面的最大的数即可。

 

挺囧的是线段树参考了别人的程序,查了老半天说我擦a不了,原来人家根本不是点树= =,还是自己理解自己写好。

树状数组
 1 //bzoj 1012
 2 const
 3         maxm=211111;
 4         inf='1.txt';
 5 var
 6         tree, a: array[0..maxm]of longint;
 7         t, m, d, tot: longint;
 8 function lowbit(x: longint): longint;
 9 begin exit(x and (-x)); end;
10 
11 procedure init;
12 begin
13   fillchar(tree, sizeof(tree), 0);
14   fillchar(a, sizeof(a), 0);
15   tot := 0; t := 0;
16   readln(m, d);
17 end;
18 
19 function find(start, l: longint): longint;
20 var
21         i, tmp, ed: longint;
22 begin
23   if start=0 then exit(0);
24   tmp := 0; i := start;
25   ed := start-l+1;
26   while (i>=ed)and(i>0) do begin
27     if a[i]>tmp then tmp := a[i];
28     dec(i);
29     while (i-lowbit(i)>=ed)and(i>0) do begin
30       if tree[i]>tmp then tmp := tree[i];
31       i := i - lowbit(i);
32     end;
33   end;
34   find := tmp;
35 end;
36 
37 procedure main;
38 var
39         i, l, tmp: longint;
40         n: int64;
41         c: char;
42 begin
43   for i := 1 to m do begin
44     read(c);
45     if c='A' then begin
46       readln(n);
47       n := (t + n) mod d;
48       inc(tot);
49       a[tot] := longint(n);
50       tmp := find(tot-1, lowbit(tot)-1);
51       if tmp>a[tot] then tree[tot] := tmp
52         else tree[tot] := a[tot];
53     end
54     else begin
55       readln(l);
56       t := find(tot, l);
57       writeln(t);
58     end;
59   end;
60 end;
61 
62 begin
63   assign(input,inf); reset(input);
64   init;
65   main;
66 end.
线段树
 1 //bzoj 1012
 2 const
 3         maxn=211111;
 4         inf='1.txt';
 5 type
 6         type_node=record
 7           l, r, mid, st, ed, max: longint;
 8         end;
 9 var
10         tree: array[0..maxn*4]of type_node;
11         m, d, t, tot: longint;
12 procedure build(b, e, k: longint);
13 begin
14   with tree[k] do begin
15     st := b; ed := e; mid := (st+ed)>>1;
16     if st=ed then exit;
17     l := k << 1; build(st, mid, l);
18     r := l + 1; build(mid+1, ed, r);
19   end;
20 end;
21 
22 procedure init;
23 begin
24   t := 0; tot := 0;
25   fillchar(tree, sizeof(tree), 0);
26   readln(m, d);
27   build(1, m, 1);
28 end;
29 
30 function _max(a, b: longint): longint;
31 begin if a>b then exit(a) else exit(b); end;
32 
33 procedure add(b, e, num, k: longint);
34 var
35         tmp: longint;
36 begin
37   with tree[k] do begin
38     if num>max then max := num;
39     if st=ed then exit;
40     if b<=mid then add(b, e, num, l);
41     if e>mid then add(b, e, num, r);
42   end;
43 end;
44 
45 function ask(b, e, k: longint): longint;
46 var
47         tmp: longint;
48 begin
49   with tree[k] do begin
50     if (b<=st)and(ed<=e) then exit(max);
51     tmp := 0; ask := 0;
52     if b<=mid then tmp := ask(b, e, l);
53     if e>mid then ask := ask(b, e, r);
54     if tmp>ask then ask := tmp;
55   end;
56 end;
57 
58 procedure main;
59 var
60         i, n, l: longint;
61         c: char;
62 begin
63   for i := 1 to m do begin
64     read(c);
65     if c='A' then begin
66       read(n ); inc(tot);
67       n := (n+t)mod d;
68       add(tot-1, tot, n, 1);
69     end
70     else begin
71       read(l);
72       t := ask(tot-l+1, tot, 1);
73       writeln(t);
74     end;
75     readln;
76   end;
77 end;
78 
79 begin
80   assign(input,inf); reset(input);
81   init;
82   main;
83 end.
单调队列+并查集
 1 //bzoj 1012
 2 const
 3         inf='1.txt';
 4         maxn=211111;
 5 var
 6         fa, a, d: array[0..maxn]of longint;
 7         t, m, mo, a_tot, d_tot: longint;
 8 function getfather(x: longint): longint;
 9 begin
10   if x=fa[x] then exit(x);
11   fa[x] := getfather(fa[x]);
12   exit(fa[x]);
13 end;
14 
15 procedure init;
16 begin
17   t := 0; a_tot := 0; d_tot := 0;
18   readln(m, mo);
19   fillchar(fa, sizeof(fa), 0);
20   fillchar(a, sizeof(a), 0);
21   fillchar(d, sizeof(d), 0);
22   a[0] := maxlongint;
23 end;
24 
25 procedure main;
26 var
27         i, l, n, w: longint;
28         c: char;
29 begin
30   for i := 1 to m do begin
31     read(c);
32     if c='A' then begin
33       read(n);
34       n := (n+t) mod mo;
35       inc(a_tot); a[a_tot] := n;
36       fa[a_tot] := a_tot;
37       while a[d[d_tot]] < a[a_tot] do begin
38         fa[d[d_tot]] := a_tot;
39         dec(d_tot);
40       end;
41       inc(d_tot); d[d_tot] := a_tot;
42     end
43     else begin
44       read(l);
45       w := getfather(a_tot-l+1);
46       t := a[w];
47       writeln(a[w]);
48     end;
49     readln;
50   end;
51 end;
52 
53 begin
54   assign(input,'1.txt'); reset(input);
55   init;
56   main;
57 end.
posted @ 2012-04-10 20:00  F.D.His.D  阅读(220)  评论(0编辑  收藏  举报