• 【BZOJ3123】森林(主席树,启发式合并)


    题意:一个带点权的森林,要求维护以下操作:

    1.询问路径上的点权K大值

    2.两点之间连边

    n,m<=80000

    思路:如果树的结构不发生变化只需要维护DFS序

    现在因为树的结构发生变化,要将两棵树合并,这步可以用启发式合并,将比较小的树暴力连接到较大的树上面

    离线的LCA算法无法维护,而倍增可以合并,所以用倍增求LCA

    其余就是主席树,维护根到点的权值线段树就行了

    机房里的罗爷爷写法比我高到不知道哪里去了

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 using namespace std;
     5 const int M=200010;
     6 int cas,n,m,q,i,x,y,k,edgenum,cnt,ans;
     7 int a[M],b[M],c[M],head[M],vet[M],next[M],dep[M],fa[M][20],f[M],size[M],root[M];
     8 struct node{int l,r,w;}tree[M*100];
     9 bool cmp(int x,int y){return a[x]<a[y];}
    10 int search(int x){
    11     if (f[x]!=x)f[x]=search(f[x]);
    12     return f[x];
    13 }
    14 void addedge(int x,int y){
    15     vet[++edgenum]=y;
    16     next[edgenum]=head[x];
    17     head[x]=edgenum;
    18 }
    19 void update(int x,int l,int r,int &p){
    20     tree[++cnt]=tree[p];p=cnt;tree[p].w++;
    21     if (l==r)return;
    22     int mid=l+r>>1;
    23     if (x<=mid)update(x,l,mid,tree[p].l);
    24         else update(x,mid+1,r,tree[p].r);
    25 }
    26 int query(int l,int r,int k,int x,int y,int z,int w){
    27     if (l==r)return l;
    28     int mid=l+r>>1,t=tree[tree[x].l].w+tree[tree[y].l].w-tree[tree[z].l].w-tree[tree[w].l].w;
    29     if (t>=k)return query(l,mid,k,tree[x].l,tree[y].l,tree[z].l,tree[w].l);
    30         else return query(mid+1,r,k-t,tree[x].r,tree[y].r,tree[z].r,tree[w].r);
    31 }
    32 int lca(int x,int y){
    33     if (dep[x]<dep[y])swap(x,y);
    34     int t=dep[x]-dep[y];
    35     for (int i=0;i<=16;i++)
    36         if (t&(1<<i))x=fa[x][i];
    37     for (int i=16;i>=0;i--)
    38         if (fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
    39     if (x==y)return x;
    40     return fa[x][0];
    41 }
    42 void dfs(int u,int pre){
    43     fa[u][0]=pre;
    44     for (int i=1;i<=16;i++)fa[u][i]=fa[fa[u][i-1]][i-1];
    45     root[u]=root[pre];
    46     update(c[u],1,n,root[u]);
    47     for (int e=head[u];e;e=next[e]){
    48         int v=vet[e];
    49         if (v==pre)continue;
    50         dep[v]=dep[u]+1;
    51         dfs(v,u);
    52     }
    53 }
    54 void link(int x,int y){
    55     int p=search(x),q=search(y);
    56     if (size[p]>size[q]){swap(x,y);swap(p,q);}
    57     dep[x]=dep[y]+1;
    58     dfs(x,y);
    59     f[p]=q;size[q]+=size[p];
    60     addedge(x,y);
    61     addedge(y,x);
    62 }
    63 int main(){
    64     scanf("%d",&cas);
    65     scanf("%d%d%d",&n,&m,&q);
    66     for (i=1;i<=n;i++)scanf("%d",&a[i]),b[i]=i;
    67     sort(b+1,b+n+1,cmp);
    68     for (i=1;i<=n;i++)c[b[i]]=i;
    69     for (i=1;i<=n;i++)f[i]=i,size[i]=1;
    70     cnt=n;
    71     for (i=1;i<=n;i++)root[i]=i,update(c[i],1,n,root[i]);
    72     for (i=1;i<=m;i++){
    73         scanf("%d%d",&x,&y);
    74         link(x,y);
    75     }
    76     while (q--){
    77         char s[10];
    78         scanf("%s",s);
    79         if (s[0]=='L'){
    80             scanf("%d%d",&x,&y);
    81             x^=ans;y^=ans;
    82             link(x,y);
    83         }else{
    84             scanf("%d%d%d",&x,&y,&k);
    85             x^=ans;y^=ans;k^=ans;
    86             int z=lca(x,y);
    87             printf("%d
    ",ans=a[b[query(1,n,k,root[x],root[y],root[z],root[fa[z][0]])]]);
    88         }
    89     }
    90 }

    这是我的萎靡写法

      1 var t:array[0..22000000]of record
      2                            l,r,s:longint;
      3                           end;
      4     f:array[0..300000,0..20]of longint;
      5     root,head,c,a,hash,h,dep,stk,size:array[0..500000]of longint;
      6     vet,next:array[0..610000]of longint;
      7     n,m,x,y,z,lastans,i,j,tot,cnt,k,s,up,top,que:longint;
      8     ch:string;
      9 
     10 procedure swap(var x,y:longint);
     11 var t:longint;
     12 begin
     13  t:=x; x:=y; y:=t;
     14 end;
     15 
     16 procedure qsort(l,r:longint);
     17 var i,j,mid:longint;
     18 begin
     19  i:=l; j:=r; mid:=c[(l+r)>>1];
     20  repeat
     21   while mid>c[i] do inc(i);
     22   while mid<c[j] do dec(j);
     23   if i<=j then
     24   begin
     25    swap(c[i],c[j]);
     26    inc(i); dec(j);
     27   end;
     28  until i>j;
     29  if l<j then qsort(l,j);
     30  if i<r then qsort(i,r);
     31 end;
     32 
     33 function lsh(x:longint):longint;
     34 var l,r,mid:longint;
     35 begin
     36  l:=1; r:=up;
     37  while l<=r do
     38  begin
     39   mid:=(l+r)>>1;
     40   if x=hash[mid] then exit(mid);
     41   if x<hash[mid] then r:=mid-1
     42    else l:=mid+1;
     43  end;
     44 end;
     45 
     46 function find(k:longint):longint;
     47 begin
     48  if h[k]<>k then h[k]:=find(h[k]);
     49  exit(h[k]);
     50 end;
     51 
     52 procedure add(a,b:longint);
     53 begin
     54  inc(tot);
     55  next[tot]:=head[a];
     56  vet[tot]:=b;
     57  head[a]:=tot;
     58 end;
     59 
     60 procedure pushup(p:longint);
     61 begin
     62  t[p].s:=t[t[p].l].s+t[t[p].r].s;
     63 end;
     64 
     65 procedure update(l,r,x:longint;var y:longint;v:longint);
     66 var mid:longint;
     67 begin
     68  inc(cnt); y:=cnt;
     69  t[y]:=t[x]; inc(t[y].s);
     70  if l=r then exit;
     71  mid:=(l+r)>>1;
     72  if v<=mid then update(l,mid,t[x].l,t[y].l,v)
     73   else update(mid+1,r,t[x].r,t[y].r,v);
     74  pushup(y);
     75 end;
     76 
     77 procedure dfs(u,pre:longint);
     78 var e,v,x,y:longint;
     79 begin
     80  update(1,up,root[pre],root[u],a[u]);
     81  e:=head[u];
     82  dep[u]:=dep[pre]+1;
     83  f[u,0]:=pre;
     84  while e<>0 do
     85  begin
     86   v:=vet[e];
     87   if v<>pre then
     88   begin
     89    dfs(v,u);
     90    x:=find(v); y:=find(u);
     91    if size[x]<size[y] then
     92    begin
     93     size[x]:=size[y]+size[x];
     94     h[y]:=x;
     95    end
     96     else begin size[y]:=size[x]+size[y]; h[x]:=y; end;
     97   end;
     98   e:=next[e];
     99  end;
    100 end;
    101 
    102 function lca(x,y:longint):longint;
    103 var i,d:longint;
    104 begin
    105  if dep[x]<dep[y] then swap(x,y);
    106  d:=dep[x]-dep[y];
    107  for i:=0 to 20 do
    108   if d and (1<<i)>0 then x:=f[x,i];
    109  for i:=20 downto 0 do
    110   if f[x,i]<>f[y,i] then
    111   begin
    112    x:=f[x,i]; y:=f[y,i];
    113   end;
    114  if x=y then exit(x);
    115  exit(f[x,0]);
    116 end;
    117 
    118 function query(l,r,x,y,z,w,k:longint):longint;
    119 var mid,tmp:longint;
    120 begin
    121  if l=r then exit(l);
    122  mid:=(l+r)>>1;
    123  tmp:=t[t[x].l].s+t[t[y].l].s-t[t[z].l].s-t[t[w].l].s;
    124  if tmp>=k then
    125  begin
    126   x:=t[x].l; y:=t[y].l; z:=t[z].l; w:=t[w].l;
    127   exit(query(l,mid,x,y,z,w,k));
    128  end
    129   else
    130   begin
    131    x:=t[x].r; y:=t[y].r; z:=t[z].r; w:=t[w].r;
    132    exit(query(mid+1,r,x,y,z,w,k-tmp));
    133   end;
    134 end;
    135 
    136 function ask(x,y,z:longint):longint;
    137 var q:longint;
    138 begin
    139  q:=lca(x,y);
    140  exit(hash[query(1,up,root[x],root[y],root[q],root[f[q,0]],z)]);
    141 end;
    142 
    143 procedure rebuild(u,pre:longint);
    144 var e,v:longint;
    145 begin
    146  inc(top); stk[top]:=u;
    147  update(1,up,root[pre],root[u],a[u]);
    148  dep[u]:=dep[pre]+1;
    149  f[u,0]:=pre;
    150  e:=head[u];
    151  while e<>0 do
    152  begin
    153   v:=vet[e];
    154   if v<>pre then rebuild(v,u);
    155   e:=next[e];
    156  end;
    157 end;
    158 
    159 procedure merge(x,y:longint);
    160 var tx,ty,z,i,j:longint;
    161 begin
    162  tx:=find(x); ty:=find(y);
    163  if size[tx]>size[ty] then
    164  begin
    165   swap(tx,ty); swap(x,y);
    166  end;
    167  top:=0;
    168  add(x,y); add(y,x);
    169  rebuild(x,y);
    170  h[tx]:=ty; size[ty]:=size[ty]+size[tx];
    171  for i:=1 to 20 do
    172   for j:=1 to top do
    173   begin
    174    z:=stk[j];
    175    f[z,i]:=f[f[z,i-1],i-1];
    176   end;
    177 end;
    178 
    179 begin
    180  assign(input,'bzoj3123.in'); reset(input);
    181  assign(output,'bzoj3123.out'); rewrite(output);
    182  readln(x);
    183  readln(n,m,que);
    184  for i:=1 to n do
    185  begin
    186   read(a[i]);
    187   c[i]:=a[i];
    188  end;
    189  qsort(1,n);
    190  up:=1; hash[1]:=c[1];
    191  for i:=2 to n do
    192   if c[i]<>c[i-1] then begin inc(up); hash[up]:=c[i]; end;
    193  for i:=1 to n do a[i]:=lsh(a[i]);
    194  for i:=1 to m do
    195  begin
    196   readln(x,y);
    197   add(x,y);
    198   add(y,x);
    199  end;
    200  for i:=1 to n do
    201  begin
    202   h[i]:=i; size[i]:=1;
    203  end;
    204  for i:=1 to n do
    205   if root[i]=0 then dfs(i,0);
    206  for i:=1 to 20 do
    207   for j:=1 to n do f[j,i]:=f[f[j,i-1],i-1];
    208  for i:=1 to que do
    209  begin
    210   readln(ch); s:=0; k:=length(ch); x:=0; y:=0; z:=0;
    211   for j:=2 to k do
    212   begin
    213    if ch[j]=' ' then begin if ch[j-1]<>' ' then inc(s); continue; end;
    214    if s=1 then x:=x*10+ord(ch[j])-ord('0');
    215    if s=2 then y:=y*10+ord(ch[j])-ord('0');
    216    if s=3 then z:=z*10+ord(ch[j])-ord('0');
    217   end;
    218   if ch[1]='Q' then
    219   begin
    220    x:=x xor lastans; y:=y xor lastans; z:=z xor lastans; //writeln(x,' ',y,' ',z);
    221    k:=ask(x,y,z);
    222    writeln(k);
    223    lastans:=k;
    224   end
    225    else
    226    begin
    227     x:=x xor lastans; y:=y xor lastans;// writeln(x,' ',y,' ',z);
    228     merge(x,y);
    229    end;
    230 
    231  end;
    232  close(input);
    233  close(output);
    234 end.
  • 相关阅读:
    微信小程序HTTPS
    微信商城-1简介
    va_list
    Event log c++ sample.
    EVENT LOGGING
    Analyze Program Runtime Stack
    unknow table alarmtemp error when drop database (mysql)
    This application has request the Runtime to terminate it in an unusual way.
    How to check if Visual Studio 2005 SP1 is installed
    SetUnhandledExceptionFilter
  • 原文地址:https://www.cnblogs.com/myx12345/p/6242940.html
Copyright © 2020-2023  润新知