您的位置:首页 > 其它

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

2017-01-02 18:47 696 查看

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

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=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\n",ans=a[b[query(1,n,k,root[x],root[y],root[z],root[fa[z][0]])]]); 88 } 89 } 90 }

[p]这是我的萎靡写法

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

.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.

[p] 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: