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.