Description
馒头卡得了忧郁综合症,包子卡正在想办法开导她。
机智的白子卡决定陪着馒头卡玩游戏,他从魔法世界里变出一张无向连通图,每条边上都有边权。包子卡定义一条路径的权值为经过边中的最大权值,馒头卡则定义两点的 最短路径为所有路径中权值最小的路径权。
每次馒头卡先选出两个点 m1,m2 m1,m2,然后包子卡会拿出两堆灵魂宝石,一堆有 m m 个,另一堆有 b b 个。然后馒头卡先从一堆中选出若干个灵魂宝石拿走,接下来包子卡重复同样的操作,如此反复,直到取走最后一颗灵魂宝石,然后取走最后一颗宝石的人获胜。
包子卡认为这样游戏太简单,于是他会不定期向这张图上加上一些边,以增大游戏难度。
馒头卡具有预知未来的能力,她看到了自己和包子卡在未来游戏中的选择,以及包子卡增加的边。现在对于每次游戏,馒头卡想知道自己是否存在必胜的方法,但是预知未来已经消耗了她太多精力,出于疲惫她只好找到了你。
Input
第一行两个数 N N 和 M M ,表示这张无向图初始的点数和边数。
接下来 M M 行,每行三个数 u,v,q u,v,q 表示点 u u 和点 v v 之间存在一条权值为 q q 的边。
接下来一行一个数 Q Q,表示操作总数。
接下来 Q Q 行,表示操作,每行格式为下面两条中的一条:
1 add u v q:1 add u v q:表示在 u u 与 v v 之间加上一条边权为 q q 的边。
2 game m1 m2 b1 b22 game m1 m2 b1 b2:表示一次游戏,其中馒头卡的选择点 m1,m2m1,m2,包子卡的选择点b1,b2b1,b2。
Output
对于每个 gamegame 输出一行,若馒头卡存在必胜策略,则输出‘madoka′‘madoka′,否则输出‘Baozika′‘Baozika′,以回车结尾。
Sample Input
5 6
1 2 3
2 3 6
4 2 4
5 3 5
3 4 5
5 1 5
4
game 1 3 4 3
game 1 5 2 4
add 2 5 4
game 1 5 3 4
Sample Output
Baozika
madoka
madoka
Data Constraint
N≤5000;M≤100000;Q≤150000;N≤5000;M≤100000;Q≤150000;
边权q≤1015q≤1015;addadd 操作数≤1000≤1000
数据保证 1≤u,v,m1,m2,b1,b2≤n, 1≤q,1≤u,v,m1,m2,b1,b2≤n, 1≤q,
m1≠m2 且 b1≠b2m1≠m2 且 b1≠b2
Solution
就是求两点间最小的瓶颈路,瓶颈路就是一条路径上最大的那条边。
先考虑什么时候包子卡赢,什么时候馒头卡赢。如果存在两个数S1=S2S1=S2,假设一个人在S1S1中取了 a a ,那只要相应的在另一堆 S2 S2 中取 a a 个就可以了,这样最后保证后手必赢。相应的如果一开始S1≠S2S1≠S2,则先手赢。
那两点的最小瓶颈路是什么呢,其实就是对应着整幅图的最小生成树,用LCA倍增上去就可以得到瓶颈路了。
可以发现,addadd操作数很小,所以每次可以从两点LCALCA倍增上去找到瓶颈路,也就是最大值,把那条路打个tagtag封住,连接新边,从LCALCA上往下全部更新一遍即可。
Code
const maxn=7005;
maxm=150000;
w=13;
var n,m,i,tot,q:longint;
c:char;
g,fa,deep:array[0..maxn] of longint;
a:array[0..maxm,1..2] of longint;
len:array[0..maxm] of int64;
f,e:array[0..maxn,0..w] of longint;
ll:array[0..maxn,0..w] of int64;
next,yy:array[1..maxn*2] of longint;
cost:array[1..maxn*2] of int64;
p:array[0..maxm] of boolean;
function make(x,y:longint;z:int64):longint;
begin
inc(tot);
yy[tot]:=y;
cost[tot]:=z;
next[tot]:=g[x];
g[x]:=tot;
end;
procedure swap(var x,y:longint);
var t:longint;
begin
t:=x;
x:=y;
y:=t;
end;
function dis(x,y:longint):int64;
var v,i,l:longint;
len:int64;
begin
if deep[x]<deep[y] then swap(x,y);
l:=deep[x]-deep[y];v:=0;
len:=-high(int64);
while l<>0 do begin
if l mod 2=1 then begin
if len<ll[x,v] then len:=ll[x,v];
x:=f[x,v];
end;
l:=l div 2;
inc(v);
end;
if x=y then exit(len);
for i:=w downto 0 do begin
while f[x,i]<>f[y,i] do begin
if len<ll[x,i] then len:=ll[x,i];
x:=f[x,i];
if len<ll[y,i] then len:=ll[y,i];
y:=f[y,i];
end;
end;
if len<ll[x,0] then len:=ll[x,0];
if len<ll[y,0] then len:=ll[y,0];
exit(len);
end;
procedure query(x1,y1,x2,y2:longint);
var a1,a2:int64;
begin
a1:=dis(x1,y1);
a2:=dis(x2,y2);
if a1=a2 then writeln('Baozika') else
writeln('madoka');
end;
procedure qsort(x,y:longint);
var i,j:longint;
k:int64;
begin
i:=x;
j:=y;
k:=len[(x+y) div 2];
repeat
while len[i]<k do inc(i);
while len[j]>k do dec(j);
if i<=j then begin
a[0]:=a[i];
a[i]:=a[j];
a[j]:=a[0];
len[0]:=len[i];
len[i]:=len[j];
len[j]:=len[0];
inc(i);dec(j);
end;
until i>j;
if i<y then qsort(i,y);
if j>x then qsort(x,j);
end;
procedure init;
var i:longint;
begin
readln(n,m);
for i:=1 to m do
readln(a[i,1],a[i,2],len[i]);
end;
function get(x:longint):longint;
begin
if fa[x]=x then exit(x);
fa[x]:=get(fa[x]);
exit(fa[x]);
end;
procedure build;
var i,fax,fay:longint;
begin
for i:=1 to n do fa[i]:=i;
for i:=1 to m do begin
fax:=get(a[i,1]);
fay:=get(a[i,2]);
if fax<>fay then begin
fa[fax]:=fay;
make(a[i,1],a[i,2],len[i]);
make(a[i,2],a[i,1],len[i]);
end;
end;
end;
procedure dfs(x:longint);
var i,y:longint;
begin
for i:=1 to w do begin
f[x,i]:=0;
ll[x,i]:=0;
e[x,i]:=0;
end;
for i:=1 to w do if f[x,i-1]=0 then break else begin
if ll[x,i-1]>=ll[f[x,i-1],i-1] then begin
ll[x,i]:=ll[x,i-1];
e[x,i]:=e[x,i-1];
end else begin
ll[x,i]:=ll[f[x,i-1],i-1];
e[x,i]:=e[f[x,i-1],i-1];
end;
f[x,i]:=f[f[x,i-1],i-1];
end;
i:=g[x];
while i<>0 do begin
y:=yy[i];
if (p[i]) and (f[x,0]<>y) then begin
deep[y]:=deep[x]+1;
f[y,0]:=x;
ll[y,0]:=cost[i];
e[y,0]:=i;
dfs(y);
end;
i:=next[i];
end;
end;
procedure change(x0,y0:longint;z:int64);
var i,l,v,x,y,ei:longint;
len:int64;
begin
x:=x0;y:=y0;
if deep[x]<deep[y] then swap(x,y);
l:=deep[x]-deep[y];v:=0;len:=-high(int64);
while l<>0 do begin
if l mod 2=1 then begin
if len<ll[x,v] then begin
len:=ll[x,v];
ei:=e[x,v];
end;
x:=f[x,v];
end;
l:=l div 2;
inc(v);
end;
if x<>y then begin
for i:=w downto 0 do begin
while f[x,i]<>f[y,i] do begin
if len<ll[x,i] then begin
len:=ll[x,i];
ei:=e[x,i];
end;
x:=f[x,i];
if len<ll[y,i] then begin
len:=ll[y,i];
ei:=e[y,i];
end;
y:=f[y,i];
end;
end;
if len<ll[x,0] then begin
len:=ll[x,0];
ei:=e[x,i];
end;
if len<ll[y,0] then begin
len:=ll[y,0];
ei:=e[y,i];
end;
x:=f[x,0];
end;
if z>len then exit;
make(x0,y0,z);
make(y0,x0,z);
p[ei]:=false;
p[ei xor 1]:=false;
dfs(x);
end;
procedure main;
var j,i,x,y,x1,y1,x2,y2:longint;
z:int64;
begin
tot:=1;
fillchar(p,sizeof(p),true);
qsort(1,m);
build;
dfs(1);
readln(q);
for i:=1 to q do begin
read(c);
if c='g' then begin
while c<>' ' do read(c);
readln(x1,y1,x2,y2);
query(x1,y1,x2,y2);
end else begin
while c<>' ' do read(c);
readln(x,y,z);
change(x,y,z);
end;
end;
end;
begin
init;
main;
end.