bzoj3524这是我主席树的第一题
什么是主席树呢,就是n棵线段树,每棵线段树记录前缀每个数值(显然想到里离散化)出现次数
由于第i棵树相对于第i-1棵树只有logS个点不同(S为数值的种类数)
所以总的空间复杂度为O(nlogS),非常好理解;
由于每棵线段树的形态都是一样的,所以这些线段树是可以做减法的,
这是一个非常有用的性质,也很好的解决了区间的性质
然后解决这道题,这题问区间出现次数超过(r-l+1)/2的数,显然直接顺着主席树搜就可以了logS的复杂度
bzoj2223基本同样的题目,注意样例n后面多了个ai的范围
1 type node=record 2 l,r,s:longint; 3 end; 4 5 var tree:array[0..10000010] of node; 6 sum,head,a,b,rank,sa:array[0..500010] of longint; 7 x,y,i,n,m,t,len,p:longint; 8 9 procedure swap(var a,b:longint); 10 var c:longint; 11 begin 12 c:=a; 13 a:=b; 14 b:=c; 15 end; 16 17 procedure sort(l,r: longint); 18 var i,j,x: longint; 19 begin 20 i:=l; 21 j:=r; 22 x:=a[(l+r) shr 1]; 23 repeat 24 while a[i]<x do inc(i); 25 while x<a[j] do dec(j); 26 if not(i>j) then 27 begin 28 swap(a[i],a[j]); 29 swap(b[i],b[j]); 30 inc(i); 31 j:=j-1; 32 end; 33 until i>j; 34 if l<j then sort(l,j); 35 if i<r then sort(i,r); 36 end; 37 38 procedure update(x:longint); 39 begin 40 tree[x].s:=tree[tree[x].l].s+tree[tree[x].r].s; 41 end; 42 43 function build(l,r:longint):longint; 44 var m,q:longint; 45 begin 46 inc(t); 47 q:=t; 48 if l=r then exit(t) 49 else begin 50 m:=(l+r) shr 1; 51 tree[q].l:=build(l,m); 52 tree[q].r:=build(m+1,r); 53 end; 54 exit(q); 55 end; 56 57 function pre(w,l,r:longint):longint; 58 var m,q:longint; 59 begin 60 inc(t); 61 q:=t; 62 if l=r then 63 tree[t].s:=sum[l] 64 else begin 65 m:=(l+r) shr 1; 66 if rank[i]<=m then 67 begin 68 tree[q].l:=pre(tree[w].l,l,m); 69 tree[q].r:=tree[w].r; 70 end 71 else begin 72 tree[q].l:=tree[w].l; 73 tree[q].r:=pre(tree[w].r,m+1,r); 74 end; 75 update(q); 76 end; 77 exit(q); 78 end; 79 80 function ask(x,y,l,r:longint):longint; 81 var m,a,b:longint; 82 begin 83 if l=r then 84 begin 85 if tree[y].s-tree[x].s>len then 86 exit(sa[l]) 87 else exit(0); 88 end 89 else begin 90 m:=(l+r) shr 1; 91 if tree[y].s-tree[x].s<=len then exit(0); 92 a:=tree[x].l; 93 b:=tree[y].l; 94 if tree[b].s-tree[a].s>len then exit(ask(a,b,l,m)); 95 a:=tree[x].r; 96 b:=tree[y].r; 97 if tree[b].s-tree[a].s>len then exit(ask(a,b,m+1,r)); 98 exit(0); 99 end; 100 end; 101 102 begin 103 readln(n,m); 104 for i:=1 to n do 105 begin 106 read(a[i]); 107 b[i]:=i; 108 end; 109 sort(1,n); 110 p:=1; 111 rank[b[1]]:=1; 112 sa[1]:=a[1]; 113 for i:=2 to n do 114 begin 115 if a[i]<>a[i-1] then 116 begin 117 inc(p); 118 sa[p]:=a[i]; 119 end; 120 rank[b[i]]:=p; 121 end; 122 t:=0; 123 head[0]:=build(1,p); 124 for i:=1 to n do 125 begin 126 inc(sum[rank[i]]); 127 head[i]:=pre(head[i-1],1,p); 128 end; 129 for i:=1 to m do 130 begin 131 readln(x,y); 132 len:=(y-x+1) shr 1; 133 writeln(ask(head[x-1],head[y],1,p)); 134 end; 135 end.