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.
View Code

 

posted on 2014-09-03 20:54  acphile  阅读(134)  评论(0编辑  收藏  举报