zoukankan      html  css  js  c++  java
  • 划分树

    至此,我的划分树模版终于完成

     1 const maxn=100000+10;
     2 var s,t:array[0..20,0..maxn] of longint;
     3     a,b,rk:array[0..maxn] of longint;
     4     i,j,n,m,x,y,k:longint;
     5 procedure sort(l,r:longint);
     6  var i,j,m,temp:longint;
     7  begin
     8  i:=l;j:=r;x:=a[(i+j)>>1];
     9  repeat
    10   while b[a[i]]<b[x] do inc(i);
    11   while b[a[j]]>b[x] do dec(j);
    12   if i<=j then
    13    begin
    14    y:=a[i];a[i]:=a[j];a[j]:=y;
    15    inc(i);dec(j);
    16    end;
    17  until i>j;
    18  if i<r then sort(i,r);
    19  if j>l then sort(l,j);
    20  end;
    21 procedure init;
    22  begin
    23  readln(n,m);
    24  for i:=1 to n do read(b[i]);
    25  for i:=1 to n do a[i]:=i;
    26  sort(1,n);
    27  end;
    28 procedure build(h,l,r:longint);
    29  var i,p,mid:longint;
    30  begin
    31  mid:=(l+r)>>1;p:=0;
    32  for i:=l to r do
    33   if t[h,i]<=mid then
    34    begin
    35     t[h+1,l+p]:=t[h,i];
    36     inc(p);
    37     s[h,i]:=p;
    38    end
    39   else
    40    begin
    41     t[h+1,mid+1+i-p-l]:=t[h,i];
    42     s[h,i]:=p;
    43    end;
    44  if l=r then exit;
    45  build(h+1,l,mid);
    46  build(h+1,mid+1,r);
    47  end;
    48 function find(h,l,r,x,y,k:longint):longint;
    49  var ll,rr,mid:longint;
    50  begin
    51  if l=r then exit(t[h,l]);
    52  mid:=(l+r)>>1;
    53  if l=x then ll:=0 else ll:=s[h,x-1];rr:=s[h,y]-ll;
    54  if rr>=k then exit(find(h+1,l,mid,l+ll,l+rr+ll-1,k))
    55  else exit(find(h+1,mid+1,r,mid+1+x-l-ll,mid+1+y-l-rr-ll,k-rr));
    56  end;
    57 procedure main;
    58  begin
    59  for i:=1 to n do t[0,a[i]]:=i;
    60  build(0,1,n);
    61  for i:=1 to m do
    62   begin
    63   readln(x,y,k);
    64   writeln(b[a[find(0,1,n,x,y,k)]]);
    65   end;
    66  end;
    67 begin
    68  assign(input,'input.txt');assign(output,'output.txt');
    69  reset(input);rewrite(output);
    70  init;
    71  main;
    72  close(input);close(output);
    73 end.
    View Code

    其中有一个技巧是从盾哥那里学来的,就是求sa数组,不用更改原数组,而是b[a[i]]成为一个有序数组即可,对sort稍作修改就可以

    这估计是c++党没有的福利吧(偷笑……)

    ps:貌似这个版本可以支持的操作不多,不如HDU3473求中位数,不过貌似可以开一个结构体,记录下它的原值然后乱搞也行?

    但还是把两个版本的都记一下吧

     1 var  s,t:array[0..20,0..200000] of longint;
     2      a,rk:array[0..200000] of longint;
     3      i,n,m,x,y,k,j:longint;
     4  procedure sort(l,r:longint);
     5  var i,j,m,temp:longint;
     6  begin
     7  i:=l;j:=r;m:=a[(i+j)>>1];
     8  repeat
     9   while a[i]<m do inc(i);
    10   while a[j]>m do dec(j);
    11   if i<=j then
    12    begin
    13    temp:=a[i];a[i]:=a[j];a[j]:=temp;
    14    inc(i);dec(j);
    15    end;
    16  until i>j;
    17  if i<r then sort(i,r);
    18  if j>l then sort(l,j);
    19  end;
    20   procedure init;
    21    begin
    22      readln(n,m);
    23      for i:=1 to n do read(a[i]);t[0]:=a;
    24      sort(1,n);
    25    end;
    26  procedure build(h,l,r:longint);
    27   var  mid,i,lp,rp,lm:longint;
    28   begin
    29   mid:=(l+r)>>1;lm:=mid-l+1;lp:=l;rp:=mid+1;
    30   for i:=l to mid do
    31    if a[i]<a[mid] then dec(lm);
    32   for i:=l to r do
    33    begin
    34    if i=l then s[h,i]:=0 else s[h,i]:=s[h,i-1];
    35    if t[h,i]=a[mid] then
    36     begin
    37     if lm<>0 then
    38      begin
    39      dec(lm);inc(s[h,i]);t[h+1,lp]:=t[h,i];inc(lp);
    40      end
    41     else begin t[h+1,rp]:=t[h,i];inc(rp);end;
    42     end
    43    else
    44     if t[h,i]<a[mid] then begin inc(s[h,i]);t[h+1,lp]:=t[h,i];inc(lp);end
    45    else begin t[h+1,rp]:=t[h,i];inc(rp);end;
    46    end;
    47   if l=r then exit;
    48   build(h+1,l,mid);
    49   build(h+1,mid+1,r);
    50   end;
    51  function find(h,l,r,x,y,k:longint):longint;
    52   var mid,ll,rr:longint;
    53   begin
    54   if l=r then exit(t[h,l]);
    55   mid:=(l+r)>>1;
    56   if l=x then ll:=0 else ll:=s[h,x-1];rr:=s[h,y]-ll;
    57   if rr>=k then exit(find(h+1,l,mid,l+ll,l+ll+rr-1,k))
    58   else exit(find(h+1,mid+1,r,mid+1+x-l-ll,mid+1+y-l-ll-rr,k-rr));
    59   end;
    60  procedure main;
    61   begin
    62    build(0,1,n);
    63    for i:=1 to m do
    64     begin
    65      readln(x,y,k);
    66      writeln(find(0,1,n,x,y,k));
    67     end;
    68   end;
    69 begin
    70   init;
    71   main;
    72 end.
    73            
    View Code
  • 相关阅读:
    Java面试:用set集合的时候,重写过hashcode()和equal()方法吗?有什么作用?
    Bootstrap起步
    Java NIO
    Dobbo和SpringCloud区别
    Java虚拟机类加载机制和双亲委派模型
    继承和组合的特点和区别
    LinkedList和ArrayList底层原理
    聚集索引和非聚集索引
    Stream和迭代器的区别
    悲观锁和乐观锁
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/3854233.html
Copyright © 2011-2022 走看看