首页 > 代码库 > 划分树
划分树
至此,我的划分树模版终于完成
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 repeat10 while b[a[i]]<b[x] do inc(i);11 while b[a[j]]>b[x] do dec(j);12 if i<=j then13 begin14 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 begin23 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 begin31 mid:=(l+r)>>1;p:=0;32 for i:=l to r do33 if t[h,i]<=mid then34 begin35 t[h+1,l+p]:=t[h,i];36 inc(p);37 s[h,i]:=p;38 end39 else40 begin41 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 begin51 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 begin59 for i:=1 to n do t[0,a[i]]:=i;60 build(0,1,n);61 for i:=1 to m do62 begin63 readln(x,y,k);64 writeln(b[a[find(0,1,n,x,y,k)]]);65 end;66 end;67 begin68 assign(input,‘input.txt‘);assign(output,‘output.txt‘);69 reset(input);rewrite(output);70 init;71 main;72 close(input);close(output);73 end.
其中有一个技巧是从盾哥那里学来的,就是求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 then12 begin13 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 begin22 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 begin29 mid:=(l+r)>>1;lm:=mid-l+1;lp:=l;rp:=mid+1;30 for i:=l to mid do31 if a[i]<a[mid] then dec(lm);32 for i:=l to r do33 begin34 if i=l then s[h,i]:=0 else s[h,i]:=s[h,i-1];35 if t[h,i]=a[mid] then36 begin37 if lm<>0 then38 begin39 dec(lm);inc(s[h,i]);t[h+1,lp]:=t[h,i];inc(lp);40 end41 else begin t[h+1,rp]:=t[h,i];inc(rp);end;42 end43 else44 if t[h,i]<a[mid] then begin inc(s[h,i]);t[h+1,lp]:=t[h,i];inc(lp);end45 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 begin54 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 begin62 build(0,1,n);63 for i:=1 to m do64 begin65 readln(x,y,k);66 writeln(find(0,1,n,x,y,k));67 end;68 end;69 begin70 init;71 main;72 end.73
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。