• 【BZOJ2733】永无乡(线段树,启发式合并)


    题意:支持合并,求块内K小数

    对于 100%的数据 n≤100000,m≤n,q≤300000 

    思路:对于每一个块建立一棵动态开点的线段树,暴力(启发式?)合并后二分下就行了

    merge用函数的方式写因为懒得讨论x,y其中一个为0的情况,反正是把节点y并到x上

    为什么这么暴力都不T?大概是因为随机数据的块的大小太平均了吧

      1 var t:array[0..2100000,0..1]of longint;
      2     sum:array[0..2100000]of longint;
      3     fa,a,root:array[0..300000]of longint;
      4     n,m,x,y,k,i,j,s,cnt,p,q:longint;
      5     ch:string;
      6 
      7 function find(k:longint):longint;
      8 begin
      9  if fa[k]<>k then fa[k]:=find(fa[k]);
     10  exit(fa[k]);
     11 end;
     12 
     13 procedure pushup(x:longint);
     14 var l,r:longint;
     15 begin
     16  l:=t[x,0]; r:=t[x,1];
     17  sum[x]:=sum[l]+sum[r];
     18 end;
     19 
     20 procedure update(l,r,x:longint;var p:longint);
     21 var mid:longint;
     22 begin
     23  if p=0 then
     24  begin
     25   inc(cnt); p:=cnt;
     26  end;
     27  if l=r then
     28  begin
     29   inc(sum[p]); exit;
     30  end;
     31  mid:=(l+r)>>1;
     32  if x<=mid then update(l,mid,x,t[p,0])
     33   else update(mid+1,r,x,t[p,1]);
     34  pushup(p);
     35 end;
     36 
     37 function merge(x,y:longint):longint;
     38 var mid:longint;
     39 begin
     40  if (x=0)or(y=0) then exit(x+y);
     41  t[x,0]:=merge(t[x,0],t[y,0]);
     42  t[x,1]:=merge(t[x,1],t[y,1]);
     43  pushup(x);
     44  exit(x);
     45 end;
     46 
     47 
     48 function query(l,r,k,p:longint):longint;
     49 var mid,tmp:longint;
     50 begin
     51  if sum[p]<k then exit(-1);
     52  if l=r then exit(a[l]);
     53  tmp:= sum[t[p,0]];
     54  mid:=(l+r)>>1;
     55  if tmp>=k then exit(query(l,mid,k,t[p,0]))
     56   else exit(query(mid+1,r,k-tmp,t[p,1]));
     57 end;
     58 
     59 begin
     60  assign(input,'bzoj2733.in'); reset(input);
     61  assign(output,'bzoj2733.out'); rewrite(output);
     62  readln(n,m);
     63  for i:=1 to n do
     64  begin
     65   read(x); a[x]:=i;
     66   update(1,n,x,root[i]);
     67  end;
     68  for i:=1 to n do fa[i]:=i;
     69  for i:=1 to m do
     70  begin
     71   readln(x,y);
     72   p:=find(x); q:=find(y);
     73   if p<>q then
     74   begin
     75    fa[q]:=p;
     76    merge(root[p],root[q]);
     77   end;
     78  end;
     79  readln(m);
     80  for i:=1 to m do
     81  begin
     82   readln(ch);
     83   s:=0; x:=0; y:=0; k:=length(ch);
     84   for j:=2 to k do
     85   begin
     86    if ch[j]=' ' then begin inc(s); continue; end;
     87    if s=1 then x:=x*10+ord(ch[j])-ord('0');
     88    if s=2 then y:=y*10+ord(ch[j])-ord('0');
     89   end;
     90   case ch[1] of
     91    'Q':writeln(query(1,n,y,root[find(x)]));
     92    'B':
     93    begin
     94     p:=find(x); q:=find(y);
     95     if p<>q then
     96     begin
     97      fa[q]:=p; root[p]:=merge(root[p],root[q]);
     98     end;
     99    end;
    100   end;
    101  end;
    102 
    103 
    104  close(input);
    105  close(output);
    106 end.
  • 相关阅读:
    .NET、C#和ASP.NET,ASP.NET MVC 四者之间的区别
    Row_Number()显示行号
    iframe高度宽度自适应(转)
    Windows CMD命令大全(转)
    wndows系统命令总结
    删除ORACLE目录OCI.dll文件无法删除 (转)
    IE8兼容性调试及IE 8 css hack
    backbone学习笔记:视图(View)
    js中toFixed() 的使用(转)
    backbone学习笔记:集合(Collection)
  • 原文地址:https://www.cnblogs.com/myx12345/p/6441419.html
Copyright © 2020-2023  润新知