• poj2761


    表面上看是主席树之类的区间k大

    实际上,除了主席树,还可以测各种结构

    因为题目中说,任意区间不会完全包含

    于是,我们把区间按左端点排序,依次添加,用平衡树求当前的k大

    每个狗最多被添加一次,删除一次

    所以复杂度为O(nlogn)

    被来写的是splay,结果一直WA到死

    结果改成treap,第一次写就1Y了,不错

    不过调treap需要把一组数据跑很多遍(至少我是这么认为的)

    以免出现rp过好导致错误的程序跑对……

      1 const rd=2000007;
      2 type node=record
      3        x,y,num,k:longint;
      4      end;
      5 var ans,pretty,fa,count,key,b:array[0..200100] of longint;
      6     son:array[0..200100,1..2] of longint;
      7     a:array[0..50010] of node;
      8     p,j,root,n,q,i,t,s:longint;
      9 
     10 procedure update(i:longint);
     11   begin
     12     count[i]:=count[son[i,1]]+count[son[i,2]]+1;
     13   end;
     14 
     15 function find(x:longint):longint;
     16   var p:longint;
     17   begin
     18     p:=root;
     19     repeat
     20       if b[p]=x then exit(p);
     21       if b[p]>x then p:=son[p,1]
     22       else p:=son[p,2];
     23     until false;
     24   end;
     25 
     26 function kth(x:longint):longint;    //找k大
     27   var p:longint;
     28   begin
     29     p:=root;
     30     while true do
     31     begin
     32       if count[son[p,1]]+1=x then exit(p);
     33       if count[son[p,1]]+1>x then p:=son[p,1]
     34       else begin
     35         x:=x-count[son[p,1]]-1;
     36         p:=son[p,2];
     37       end;
     38     end;
     39   end;
     40 
     41 procedure clear(i:longint);
     42   begin
     43     count[i]:=1;
     44     son[i,1]:=0;
     45     son[i,2]:=0;
     46     fa[0]:=0;
     47     count[0]:=0;
     48   end;
     49 
     50 procedure rotate(x,w:longint);   //基本的BST左右旋,和splay是一样的
     51   var y:longint;
     52   begin
     53     y:=fa[x];
     54     if fa[y]=0 then root:=x;
     55     if fa[y]<>0 then
     56     begin
     57       if son[fa[y],1]=y then son[fa[y],1]:=x
     58       else son[fa[y],2]:=x;
     59     end;
     60     fa[x]:=fa[y];
     61     son[y,3-w]:=son[x,w];
     62     fa[son[x,w]]:=y;
     63     son[x,w]:=y;
     64     fa[y]:=x;
     65     update(y);
     66     update(x);
     67   end;
     68 
     69 procedure swap(var a,b:node);
     70   var c:node;
     71   begin
     72     c:=a;
     73     a:=b;
     74     b:=c;
     75   end;
     76 
     77 procedure up(i:longint);     //类似堆的上浮操作
     78   var j:longint;
     79   begin
     80     j:=fa[i];
     81     while j<>0 do
     82     begin
     83       if key[i]<key[j] then 
     84       begin
     85         if son[j,1]=i then rotate(i,2)
     86         else rotate(i,1);
     87       end
     88       else break;
     89       j:=fa[i];
     90     end;
     91     if j=0 then root:=i;
     92   end;
     93 
     94 procedure sift(i:longint);   //类似堆的下沉操作
     95   var j1,j2:longint;
     96   begin
     97     repeat
     98       j1:=son[i,1];       //选择较小的那个孩子旋转,使下沉后还能满足小根堆的性质
     99       j2:=son[i,2];
    100       if (j1=0) and (j2=0) then break;
    101       if (j1=0) then
    102         rotate(j2,1)
    103       else if (j2=0) then
    104         rotate(j1,2)
    105       else begin
    106         if key[j1]>key[j2] then rotate(j2,1) else rotate(j1,2);
    107       end;
    108     until false;
    109   end;
    110 
    111 procedure sort(l,r: longint);
    112   var i,j,x,y: longint;
    113   begin
    114     i:=l;
    115     j:=r;
    116     x:=a[(l+r) shr 1].x;
    117     repeat
    118       while (a[i].x<x) do inc(i);
    119       while (x<a[j].x) do dec(j);
    120       if not(i>j) then
    121       begin
    122         swap(a[i],a[j]);
    123         inc(i);
    124         j:=j-1;
    125       end;
    126     until i>j;
    127     if l<j then sort(l,j);
    128     if i<r then sort(i,r);
    129   end;
    130 
    131 procedure insert(x:longint);
    132   var p:longint;
    133   begin
    134     inc(t);
    135     inc(s);
    136     clear(t);
    137     key[t]:=trunc(random(rd));    //随机生成一个优先级,这个优先级满足小根堆的性质
    138     b[t]:=x;
    139     if root=0 then
    140     begin
    141       root:=t;
    142       fa[t]:=0;
    143     end
    144     else begin
    145       p:=root;    //先插入到treap中
    146       repeat
    147         inc(count[p]);
    148         if b[p]>x then
    149         begin
    150           if son[p,1]=0 then break;
    151           p:=son[p,1];
    152         end
    153         else begin
    154           if son[p,2]=0 then break;
    155           p:=son[p,2];
    156         end;
    157       until false;
    158       fa[t]:=p;
    159       if b[p]>x then son[p,1]:=t else son[p,2]:=t;
    160       up(t);       //调整treap
    161     end;
    162   end;
    163 
    164 procedure delete(x:longint);
    165   var i,p:longint;
    166   begin
    167     i:=find(x);
    168     key[i]:=2147483647;   //只是为了清楚,treap删除是把当前节点旋转到叶节点
    169     dec(s);
    170     sift(i);
    171     p:=i;
    172     while p<>root do    //注意删除时要更改它的父亲(祖先)的子树规模
    173     begin
    174       dec(count[fa[p]]);
    175       p:=fa[p];
    176     end;
    177     if son[fa[i],1]=i then son[fa[i],1]:=0
    178     else son[fa[i],2]:=0;
    179     count[i]:=0;
    180     key[i]:=0;
    181     b[i]:=0;
    182     fa[i]:=0;
    183     if s=0 then root:=0;
    184   end;
    185 
    186 begin
    187   randomize;
    188   readln(n,q);
    189   for i:=1 to n do
    190     read(pretty[i]);
    191   readln;
    192   for i:=1 to q do
    193   begin
    194     readln(a[i].x,a[i].y,a[i].k);
    195     a[i].num:=i;
    196   end;
    197   count[0]:=0;
    198   sort(1,q);
    199   root:=0;
    200   t:=0;
    201   for i:=a[1].x to a[1].y do
    202     insert(pretty[i]);
    203   ans[a[1].num]:=b[kth(a[1].k)];
    204   for i:=2 to q do   //按顺序一次添加删除
    205   begin
    206     if a[i].x>a[i-1].y then
    207     begin
    208       root:=0;
    209       t:=0;
    210       s:=0;
    211       fillchar(fa,sizeof(fa),0);
    212       fillchar(son,sizeof(son),0);
    213       fillchar(count,sizeof(count),0);
    214       fillchar(b,sizeof(b),0);
    215       fillchar(key,sizeof(key),0);
    216       for j:=a[i].x to a[i].y do
    217       begin
    218         insert(pretty[j]);
    219       end;
    220     end
    221     else begin
    222       for j:=a[i-1].y+1 to a[i].y do
    223         insert(pretty[j]);
    224       for j:=a[i-1].x to a[i].x-1 do
    225       begin
    226         delete(pretty[j]);
    227       end;
    228     end;
    229     p:=kth(a[i].k);
    230     ans[a[i].num]:=b[p];
    231   end;
    232   for i:=1 to q do
    233     writeln(ans[i]);
    234 end.
    View Code
  • 相关阅读:
    docker 部署 nginx+php+mysql
    jquery-weui picker组件实现只选择年月
    ios端微信浏览器禁止上下滑动
    mysql 统计连续天数
    mysql 省市数据
    php 获取毫秒时间戳
    create-react-app 打包后文件路径问题
    php nginx 获取header信息
    ubuntu或者debian安装php-gd扩展错误
    php xml字符串转数组
  • 原文地址:https://www.cnblogs.com/phile/p/4473267.html
Copyright © 2020-2023  润新知