• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
AC_Artist.zig_zag
然而我依然在补题、
博客园    首页    新随笔    联系   管理    订阅  订阅

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 !
posted @ 2013-03-19 22:44  Zig_zag  阅读(450)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3