bzoj 2594 水管局长数据加强版
其实这个题就是用LCT动态地维护一棵最小生成树.. 如果正着做的话,会发现删边以后扫边表找边会很疼,于是我们反着想。 因为没要求在线,那么我们从后往前看,如果删掉那些询问里的边以后,我们求出了一棵MST,那么其他的边就永无翻身之日了。然后就无视它们好了。 用lct维护边的话依然很恶心,那么我们把边变成点(参考某神题解),这样添加和删除就直接在这个代表边的点上做就行了吧。那么我们只需要记录一下每个询问的两个点之间的边是哪个点就行了。 一开始做MST的时候,用不着findroot用并查集就行了。注意修改的时候要判断加的这条边和这两点间的最大边的大小。 可是,超时了......pascal选手的无奈。花了1个小时翻译成c++,都贴出来吧,代码不算特别长。
tube.pas
1 {$inline on} 2 const 3 maxm=1200000; 4 maxn=200000; 5 var 6 c:array[0..maxm,0..1]of longint; 7 a,val,fa,ma,po,rev:array[0..maxm]of longint; 8 d,next,s,t:array[0..2*maxm]of longint; 9 f,ans,v,l,r,u,fir:array[0..maxn]of longint; 10 ban:array[0..maxm]of boolean; 11 i,j,n,m,p,x,y,z,now,tot,sum,lca,tmp,fx,fy:longint; 12 procedure swap(var a,b:Longint); inline; 13 var 14 tmp:longint; 15 begin 16 tmp:=a; a:=b; b:=tmp; 17 end; 18 19 procedure down(x:Longint); inline; 20 begin 21 if rev[x]=1 then 22 begin 23 swap(c[x,0],c[x,1]); 24 rev[c[x,0]]:=rev[c[x,0]] xor 1; 25 rev[c[x,1]]:=rev[c[x,1]] xor 1; 26 rev[x]:=0; 27 end; 28 end; 29 30 procedure update(x:longint); inline; 31 var 32 q:longint; 33 begin 34 if x<>0 then 35 begin 36 if ma[c[x,0]]>ma[c[x,1]] then q:=0 else q:=1; 37 ma[x]:=ma[c[x,q]]; 38 po[x]:=po[c[x,q]]; 39 if val[x]>ma[x] then 40 begin 41 ma[x]:=val[x]; 42 po[x]:=x; 43 end; 44 end; 45 end; 46 47 function root(x:longint):boolean; inline; 48 begin 49 exit((c[fa[x],0]<>x)and(c[fa[x],1]<>x)); 50 end; 51 52 procedure rotate(x:longint);inline; 53 var 54 y,z,p,q:longint; 55 begin 56 y:=fa[x]; z:=fa[y]; 57 if c[y,0]=x then p:=0 else p:=1; 58 q:=p xor 1; 59 if not root(y) then if c[z,0]=y then c[z,0]:=x else c[z,1]:=x; 60 fa[x]:=z; fa[y]:=x; fa[c[x,q]]:=y; 61 c[y,p]:=c[x,q]; c[x,q]:=y; 62 update(y); 63 end; 64 65 procedure relax(x:Longint); inline; 66 begin 67 if not root(x) then relax(fa[x]); 68 down(x); update(x); 69 end; 70 71 procedure splay(x:longint); inline; 72 var 73 y,z:Longint; 74 begin 75 relax(x); 76 while not(root(x)) do 77 begin 78 y:=fa[x]; z:=fa[y]; 79 if not (root(y)) then 80 if (c[y,0]=x)xor(c[z,0]=y) then rotate(x) else rotate(y); 81 rotate(x); 82 end; 83 update(x); 84 end; 85 86 function access(x:longint):longint; inline; 87 var 88 y:longint; 89 begin 90 y:=0; 91 repeat 92 splay(x); 93 c[x,1]:=y; 94 update(x); 95 y:=x; 96 x:=fa[x]; 97 until x=0; 98 exit(y); 99 end; 100 101 procedure link(x,y:longint); inline; 102 begin 103 access(x); 104 splay(x); 105 rev[x]:=rev[x] xor 1; 106 fa[x]:=y; 107 end; 108 109 procedure cut(x,y:longint); inline; 110 begin 111 access(x); 112 splay(y); 113 if fa[x]=y then fa[x]:=0 114 else 115 begin 116 access(y); 117 splay(x); 118 fa[y]:=0; 119 end; 120 end; 121 122 function find(i:longint):longint; inline; 123 begin 124 if f[i]=0 then exit(i); 125 if f[f[i]]=0 then exit(f[i]); 126 find:=find(f[i]); 127 f[i]:=find; 128 end; 129 130 procedure sort(l,r:longint); inline; 131 var 132 i,j,x,y:Longint; 133 begin 134 i:=l; j:=r; 135 x:=a[(l+r)>>1]; 136 repeat 137 while a[i]<x do inc(i); 138 while x<a[j] do dec(j); 139 if not (i>j) then 140 begin 141 y:=a[i]; a[i]:=a[j]; a[j]:=y; 142 y:=d[i]; d[i]:=d[j]; d[j]:=y; 143 inc(i); dec(j); 144 end; 145 until i>j; 146 if l<j then sort(l,j); 147 if i<r then sort(i,r); 148 end; 149 150 procedure add(x,y,z:longint); inline; 151 begin 152 inc(tot); 153 s[tot]:=x; t[tot]:=y; val[tot]:=z; 154 next[tot]:=fir[x]; fir[x]:=tot; 155 s[tot+m]:=y; t[tot+m]:=x; 156 next[tot+m]:=fir[y]; fir[y]:=tot+m; 157 end; 158 159 begin 160 //assign(input,'tube.in'); reset(input); 161 //assign(output,'tube.out'); rewrite(output); 162 readln(n,m,p); 163 tot:=n; 164 for i:=1 to m do 165 begin 166 readln(x,y,z); 167 add(x,y,z); 168 end; 169 for i:=1 to p do 170 begin 171 readln(u[i],l[i],r[i]); 172 j:=fir[l[i]]; 173 while j>0 do 174 begin 175 if t[j]=r[i] then 176 begin 177 now:=j; 178 break; 179 end; 180 j:=next[j]; 181 end; 182 if now>n+m then now:=now-m; 183 if u[i]=2 then 184 ban[now]:=true; 185 v[i]:=now; 186 end; 187 for i:=n+1 to n+m do d[i]:=i; 188 a:=val; 189 sort(n+1,n+m); 190 sum:=0; 191 for i:=n+1 to n+m do 192 if not ban[d[i]] then 193 begin 194 fx:=find(s[d[i]]); 195 fy:=find(t[d[i]]); 196 if fx<>fy then 197 begin 198 link(d[i],s[d[i]]); 199 link(d[i],t[d[i]]); 200 f[fx]:=t[d[i]]; 201 inc(sum); 202 end; 203 if sum=n-1 then break; 204 end; 205 for i:=p downto 1 do 206 if u[i]=1 then 207 begin 208 access(l[i]); 209 lca:=access(r[i]); 210 splay(l[i]); 211 if ma[c[lca,1]]>val[lca] then ans[i]:=ma[c[lca,1]] else ans[i]:=val[lca]; 212 if l[i]<>lca then 213 if ma[l[i]]>ans[i] then ans[i]:=ma[l[i]]; 214 end 215 else 216 begin 217 access(l[i]); 218 lca:=access(r[i]); 219 splay(l[i]); 220 if ma[c[lca,1]]>val[lca] then 221 begin 222 ans[i]:=ma[c[lca,1]]; 223 tmp:=po[c[lca,1]]; 224 end 225 else 226 begin 227 ans[i]:=val[lca]; 228 tmp:=lca; 229 end; 230 if l[i]<>lca then 231 if ma[l[i]]>ans[i] then 232 begin 233 ans[i]:=ma[l[i]]; 234 tmp:=po[l[i]]; 235 end; 236 if ans[i]>val[v[i]] then 237 begin 238 cut(tmp,s[tmp]); 239 cut(tmp,t[tmp]); 240 link(v[i],l[i]); 241 link(v[i],r[i]); 242 end; 243 end; 244 for i:=1 to p do if u[i]=1 then writeln(ans[i]); 245 //close(input); 246 //close(output); 247 end.
pascal的25秒没跑完。
tube.cpp
1 #include<iostream> 2 #include<cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #define maxn 120000 6 #define maxm 1200000 7 using namespace std; 8 struct att 9 { 10 int s,n; 11 }a[maxm]; 12 int c[maxm][2]; 13 int val[maxm],fa[maxm],po[maxm],ma[maxm],rev[maxm]; 14 int next[maxm*2],s[maxm*2],t[maxm*2]; 15 int f[maxn],ans[maxn],v[maxn],l[maxn],r[maxn],u[maxn],fir[maxn]; 16 bool ban[maxm]; 17 int tot,n,m,p; 18 19 inline void down(int x) 20 { 21 if (rev[x]) 22 { 23 swap(c[x][0],c[x][1]); 24 rev[c[x][0]]^=1; 25 rev[c[x][1]]^=1; 26 rev[x]=0; 27 } 28 } 29 30 inline void update(int x) 31 { 32 int p; 33 if (x) { 34 if (ma[c[x][0]]>ma[c[x][1]]) p=0; else p=1; 35 ma[x]=ma[c[x][p]] , po[x]=po[c[x][p]]; 36 if (val[x]>ma[x]) ma[x]=val[x] , po[x]=x; 37 } 38 } 39 40 inline bool root(int x) 41 { 42 return (c[fa[x]][0]!=x)&&(c[fa[x]][1]!=x); 43 } 44 45 inline void rotate(int x) 46 { 47 int y=fa[x],z=fa[y]; 48 int p=(c[y][1]==x),q=p^1; 49 if (!root(y)) 50 if (c[z][0]==y) c[z][0]=x; else c[z][1]=x; 51 fa[x]=z; fa[y]=x; fa[c[x][q]]=y; 52 c[y][p]=c[x][q]; c[x][q]=y; 53 update(y); 54 } 55 56 inline void relax(int x) 57 { 58 if (!root(x)) relax(fa[x]); 59 down(x); 60 } 61 62 inline void splay(int x) 63 { 64 relax(x); 65 while (!root(x)) 66 { 67 int y=fa[x],z=fa[y]; 68 if (!root(y)) 69 if ((c[y][0]==x)xor(c[z][0]==y)) rotate(x); else rotate(y); 70 rotate(x); 71 } 72 update(x); 73 } 74 75 inline int access(int x) 76 { 77 int y=0; 78 for (;x;y=x,x=fa[x]) 79 { 80 splay(x); 81 c[x][1]=y; 82 update(x); 83 } 84 return y; 85 } 86 87 inline void link(int x,int y) 88 { 89 access(x); splay(x); 90 rev[x]^=1; 91 fa[x]=y; 92 } 93 94 inline void cut(int x,int y) 95 { 96 access(x); splay(y); 97 if (fa[x]==y) fa[x]=0; 98 else 99 { 100 access(y); splay(x); 101 fa[y]=0; 102 } 103 } 104 105 inline int find(int x) 106 { 107 if (f[x]==0) return x; 108 f[x]=find(f[x]); 109 return f[x]; 110 } 111 112 inline void add(int x,int y,int z) 113 { 114 s[++tot]=x; t[tot]=y; val[tot]=z; 115 next[tot]=fir[x]; fir[x]=tot; 116 s[tot+m]=y; t[tot+m]=x; 117 next[tot+m]=fir[y]; fir[y]=tot+m; 118 } 119 120 inline bool cmp(att a,att b) 121 { 122 return a.s<b.s; 123 } 124 125 int main() 126 { 127 freopen("tube.in","r",stdin); 128 freopen("tube.out","w",stdout); 129 scanf("%d %d %d",&n,&m,&p); 130 tot=n; 131 int x,y,z; 132 for (int i=1;i<=m;i++) 133 { 134 scanf("%d %d %d",&x,&y,&z); 135 add(x,y,z); 136 } 137 for (int i=1;i<=p;i++) 138 { 139 scanf("%d %d %d",&u[i],&l[i],&r[i]); 140 int now; 141 for (int j=fir[l[i]];j;j=next[j]) 142 if (t[j]==r[i]) 143 { 144 now=j; 145 break; 146 } 147 if (now>n+m) now-=m; 148 if (u[i]==2) ban[now]=1; 149 v[i]=now; 150 } 151 for (int i=n+1;i<=n+m;i++) a[i].s=val[i],a[i].n=i; 152 sort(a+n+1,a+n+m,cmp); 153 int sum=0; 154 for (int i=n+1;i<=n+m;i++) 155 if (!ban[a[i].n]) 156 { 157 int fx=find(s[a[i].n]),fy=find(t[a[i].n]); 158 if (fx!=fy) 159 { 160 link(a[i].n,s[a[i].n]); 161 link(a[i].n,t[a[i].n]); 162 f[fx]=t[a[i].n]; 163 sum++; 164 } 165 if (sum==(n-1)) break; 166 } 167 for (int i=p;i>0;i--) 168 { 169 if (u[i]==1) 170 { 171 access(l[i]); 172 int lca=access(r[i]); 173 splay(l[i]); 174 if (ma[c[lca][1]]>val[lca]) ans[i]=ma[c[lca][1]]; else ans[i]=val[lca]; 175 if (l[i]!=lca) if (ma[l[i]]>ans[i]) ans[i]=ma[l[i]]; 176 } 177 else 178 { 179 int tmp; 180 access(l[i]); 181 int lca=access(r[i]); 182 splay(l[i]); 183 if (ma[c[lca][1]]>val[lca]) ans[i]=ma[c[lca][1]] , tmp=po[c[lca][1]]; 184 else ans[i]=val[lca] , tmp=lca; 185 if (l[i]!=lca) if (ma[l[i]]>ans[i]) ans[i]=ma[l[i]] , tmp=po[l[i]]; 186 if (ans[i]>val[v[i]]) 187 { 188 cut(tmp,s[tmp]); 189 cut(tmp,t[tmp]); 190 link(v[i],l[i]); 191 link(v[i],r[i]); 192 } 193 } 194 } 195 for (int i=1;i<=p;i++) if (u[i]==1) printf("%d\n",ans[i]); 196 return 0; 197 }
c++16秒无压力。
语言歧视啊!!!
AC without art, no better than WA !