zoukankan      html  css  js  c++  java
  • bzoj3123

    首先肯定是主席树
    但这是一类“动态树”,似乎没有什么好的办法
    那就暴力呗,这里用到启发式合并,即两棵树合并,重建节点少的的那棵
    可以用并查集维护连通性
    查询主席树的建立还是和bzoj2588一样

      1 const maxn=80010;
      2 type node=record
      3        po,next:longint;
      4      end;
      5      point=record
      6        l,r,s:longint;
      7      end;
      8 
      9 var tree:array[0..maxn*200] of point;
     10     w:array[0..2*maxn] of node;
     11     size,fs,h,p,c,a,q1,q2,rank,sa,fa,d:array[0..maxn] of longint;
     12     anc:array[0..maxn,0..20] of longint;
     13     u,e,testcase,j,t,z,i,n,m,k,x,y,len,ans,s:longint;
     14     ch:char;
     15 
     16 procedure swap(var a,b:longint);
     17   var c:longint;
     18   begin
     19     c:=a;
     20     a:=b;
     21     b:=c;
     22   end;
     23 
     24 function getf(x:longint):longint;
     25   begin
     26     if fs[x]<>x then fs[x]:=getf(fs[x]);
     27     exit(fs[x]);
     28   end;
     29 
     30 procedure update(i:longint);
     31   begin
     32     tree[i].s:=tree[tree[i].l].s+tree[tree[i].r].s;
     33   end;
     34 
     35 procedure addedge(x,y:longint);
     36   begin
     37     inc(len);
     38     w[len].po:=y;
     39     w[len].next:=p[x];
     40     p[x]:=len;
     41   end;
     42 
     43 procedure union;
     44   var k1,k2:longint;
     45   begin
     46     k1:=getf(x);
     47     k2:=getf(y);
     48     if k1<>k2 then
     49     begin
     50       if size[k1]<size[k2] then swap(x,y);  //启发式合并
     51       if size[k1]>=size[k2] then
     52       begin
     53         size[k1]:=size[k1]+size[k2];
     54         fs[k2]:=k1;
     55       end
     56       else begin
     57         size[k2]:=size[k2]+size[k1];
     58         fs[k1]:=k2;
     59       end;
     60     end;
     61   end;
     62 
     63 procedure sort(l,r: longint);
     64   var i,j,x:longint;
     65   begin
     66     i:=l;
     67     j:=r;
     68     x:=a[(l+r) div 2];
     69     repeat
     70       while (a[i]<x) do inc(i);
     71       while (x<a[j]) do dec(j);
     72       if not(i>j) then
     73       begin
     74         swap(a[i],a[j]);
     75         swap(c[i],c[j]);
     76         inc(i);
     77         j:=j-1;
     78       end;
     79     until i>j;
     80     if l<j then sort(l,j);
     81     if i<r then sort(i,r);
     82   end;
     83 
     84 function build(l,r:longint):longint;
     85   var q,m:longint;
     86   begin
     87     inc(t);
     88     if l=r then exit(t)
     89     else begin
     90       q:=t;
     91       m:=(l+r) shr 1;
     92       tree[q].l:=build(l,m);
     93       tree[q].r:=build(m+1,r);
     94       exit(q);
     95     end;
     96   end;
     97 
     98 function add(last,l,r,x:longint):longint;
     99   var q,m:longint;
    100   begin
    101     inc(t);
    102     if l=r then
    103     begin
    104       tree[t].s:=tree[last].s+1;
    105       exit(t);
    106     end
    107     else begin
    108       q:=t;
    109       m:=(l+r) shr 1;
    110       if x<=m then
    111       begin
    112         tree[q].r:=tree[last].r;
    113         last:=tree[last].l;
    114         tree[q].l:=add(last,l,m,x);
    115       end
    116       else begin
    117         tree[q].l:=tree[last].l;
    118         last:=tree[last].r;
    119         tree[q].r:=add(last,m+1,r,x);
    120       end;
    121       update(q);
    122       exit(q);
    123     end;
    124   end;
    125 
    126 function getans(l,r,k:longint):longint;
    127   var m,s1:longint;
    128   begin
    129     if l=r then
    130       exit(sa[l])
    131     else begin
    132       m:=(l+r) shr 1;
    133       s1:=tree[tree[x].l].s+tree[tree[y].l].s-tree[tree[z].l].s-tree[tree[e].l].s;
    134       if s1>=k then
    135       begin
    136         x:=tree[x].l;
    137         y:=tree[y].l;
    138         z:=tree[z].l;
    139         e:=tree[e].l;
    140         exit(getans(l,m,k));
    141       end
    142       else begin
    143         x:=tree[x].r;
    144         y:=tree[y].r;
    145         z:=tree[z].r;
    146         e:=tree[e].r;
    147         k:=k-s1;
    148         exit(getans(m+1,r,k));
    149       end;
    150     end;
    151   end;
    152 
    153 function lca(x,y:longint):longint;
    154   var i,p,u,v:longint;
    155   begin
    156     if d[x]<d[y] then swap(x,y);
    157     if x=y then exit(x);
    158     p:=trunc(ln(d[x])/ln(2));
    159     if d[x]<>d[y] then
    160     begin
    161       for i:=p downto 0 do
    162         if d[x]-1 shl i>=d[y] then x:=anc[x,i];
    163     end;
    164     if x=y then exit(x);
    165     u:=x;
    166     v:=y;
    167     for i:=p downto 0 do
    168       if (anc[x,i]<>anc[y,i]) and (anc[x,i]<>0) then
    169       begin
    170         x:=anc[x,i];
    171         y:=anc[y,i];
    172       end;
    173 
    174     exit(fa[x]);
    175   end;
    176 
    177 procedure maintain(x:longint);
    178   var i,y:longint;
    179   begin
    180     for i:=1 to trunc(ln(n)/ln(2)) do
    181     begin
    182       y:=anc[x,i-1];
    183       anc[x,i]:=anc[y,i-1];
    184     end;
    185   end;
    186 
    187 procedure dfs(x:longint);
    188   var i,y:longint;
    189   begin
    190     h[x]:=add(h[fa[x]],1,s,rank[x]);
    191     maintain(x);
    192     i:=p[x];
    193     while i<>0 do
    194     begin
    195       y:=w[i].po;
    196       if fa[x]<>y then
    197       begin
    198         d[y]:=d[x]+1;
    199         fa[y]:=x;
    200         anc[y,0]:=x;
    201         dfs(y);
    202       end;
    203       i:=w[i].next;
    204     end;
    205   end;
    206 
    207 procedure connect(x,y:longint);
    208   begin
    209     fa[y]:=x;  //这棵树内的父子关系会变化
    210     anc[y,0]:=x;
    211     d[y]:=d[x]+1;
    212     dfs(y);
    213   end;
    214 
    215 begin
    216   readln(testcase);
    217   readln(n,e,m);
    218   for i:=1 to n do
    219   begin
    220     read(a[i]);
    221     c[i]:=i;
    222     fs[i]:=i;
    223     size[i]:=1;
    224   end;
    225   sort(1,n);
    226   s:=1;
    227   sa[1]:=a[1];
    228   rank[c[1]]:=1;
    229   for i:=2 to n do
    230   begin
    231     if a[i]<>a[i-1] then
    232     begin
    233       inc(s);
    234       sa[s]:=a[i];
    235     end;
    236     rank[c[i]]:=s;
    237   end;
    238 
    239   for i:=1 to e do
    240   begin
    241     readln(x,y);
    242     addedge(x,y);
    243     addedge(y,x);
    244     union;
    245   end;
    246 
    247   t:=0;
    248   h[0]:=build(1,s);
    249   for i:=1 to n do
    250     if d[i]=0 then dfs(i);
    251 
    252   ans:=0;
    253   for i:=1 to m do
    254   begin
    255     read(ch);
    256     if ch='Q' then
    257     begin
    258       readln(x,y,k);
    259       x:=x xor ans;
    260       y:=y xor ans;
    261       k:=k xor ans;
    262       z:=lca(x,y);
    263       e:=h[fa[z]];
    264       z:=h[z];
    265       x:=h[x];
    266       y:=h[y];
    267       ans:=getans(1,s,k);
    268       writeln(ans);
    269     end
    270     else begin
    271       readln(x,y);
    272       x:=x xor ans;
    273       y:=y xor ans;
    274       addedge(x,y);
    275       addedge(y,x);
    276       union;
    277       connect(x,y);
    278     end;
    279   end;
    280 end.
    View Code
  • 相关阅读:
    mac iterm2 安装 lrzsz rz sz命令
    bash rz 上传文件失败问题
    vue-router scrollBehavior无效的问题及解决方案
    dependencies devDependencies peerDependencies optionalDependencies区别
    Nuxt / Vue.js in TypeScript: Object literal may only specify known properties, but 'components' does not exist in type 'VueClass'
    NodeJS中的require和import
    Git fetch和git pull的区别, 解决Git报错:error: You have not concluded your merge (MERGE_HEAD exists).
    webstorm打开带有node_modules文件夹的工程时很卡
    CSS3自定义滚动条样式 -webkit-scrollbar
    nginx 中location和root、alias
  • 原文地址:https://www.cnblogs.com/phile/p/4473090.html
Copyright © 2011-2022 走看看