Description

小A得了忧郁综合症,小B正在想办法开导她。
机智的小B决定陪着小A玩游戏,他从魔法的世界里变出一张无向联通图,每条边上都有边权。小B定义一条路径的权值为所有经过边中的最大权值,小A则定义两点的最短路径为所有路径中权值最小的路径权。
每次小A和小B会选出k对点mi_1,mi_2,分别计算出mi_1,mi_2的最短路径ti,然后小B会拿出k堆灵魂宝石,每堆有ti个。然后小A先从一堆中选出若干个灵魂宝石拿走,接下来小B重复同样的操作,如此反复,直到取走最后一颗灵魂宝石,然后取走最后一颗宝石的人获胜。
小B认为这样游戏太简单,于是他会不定期向这张图上加上一些边,以增大游戏难度。
小A具有预知未来的能力,她看到了自己和小B在未来游戏中的选择,以及小B增加的边。现在对于每次游戏,小A想知道自己是否存在必胜的方法。但是预知未来已经消耗了她太多精力,出于疲惫她只好找到了你。

Input

第一行三个数N和M和K,表示这张无向图初始的点数与边数,以及每次询问的点对的个数;
接下来M行,每行三个数u,v,q,表示点u和点v之间存在一条权值为q的
边;
接下来一行一个数Q,表示操作总数;
接下来Q行,表示操作,每行格式为下面两条中的一条:
1.add u v q:表示在u与v之间加上一条边权为q的边;
2.game m1_1 m1_2 … mk_1 mk_2:表示一次游戏中选择的k对点。
数据保证1≤u,v,mi_1,mi_2≤n,1≤q,mi_1≠mi_2

Output

对于每个game输出一行,若小A存在必胜策略,则输出“madoka”,否则输出“Baozika”,以回车结尾

Sample Input

5 6 2
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

Solution

  • 首先考虑获胜策略。kk 堆石子,每堆石子数量为 aiai 。

  • A 和 B 玩游戏,轮流从其中某一堆石子中取出若干个石子,最后取完石子的人获胜。

  • 结论:如 a1 xor a2 xor ... xor ak=0a1\ xor\ a2\ xor\ ...\ xor\ ak=0 ,则先手输,否则先手赢,xorxor 表示异或。

  • 证明:若 a1 xor a2 xor ... xor an≠0a1\ xor\ a2\ xor\ ...\ xor\ an≠0 ,则一定可以从其中某堆石子中取出一些石子,

  • 使得剩下的石子数异或结果为 0,若 a1 xor a2 xor ... xor an=0a1\ xor\ a2\ xor\ ...\ xor\ an=0 ,

  • 则进行一次取石子操作后 a1 xor a2 xor ... xor ana1\ xor\ a2\ xor\ ...\ xor\ an 一定不等于 0,

  • 按照这样的操作下去,最后一定会出现 a1=a2= ... =an=0a1=a2=\ ...\ =an=0 的情况。

  • 问题就变成了加边和求路径长

算法1

  • 看到询问次数很少,考虑 倍增+LCA

  • 根据最小生成树的性质,我们发现路径一定在 无向图的最小生成树 上。

  • 每次维护最小生成树,完成询问用树上 LCA 即可。

  • 事实上,加入一条边只有可能改变最小生成树上的一条边。

  • 假设加边为 x,y,zx,y,z,我们可以找到 xx 到 yy 的路径上的最大边权。

  • 若该边权 >z>z ,显然将新边加入更优,否则忽略新边。

  • 再将所有边用 O(N)O(N) 的插入排序排序即可。

  • 套上在线 LCA 算法就可以愉快的 AC 了。

  • 时间复杂度 O(D∗NlogN+(Q−D)∗logN)O(D*NlogN+(Q-D)*logN) ,其中 DD 为加边次数。

  • 注意存边权要开 long longlong\ long 。

算法2

  • 如果加边次数不限呢?直接上 LCT 啊!

  • 用 Link−Cut−TreeLink-Cut-Tree 维护最小生成树即可。

  • 若当前加入的边小于当前树中边权的最大值,则将那个最大的边删去,再连当前边。

  • 维护边权的话可以开一个虚点存边权,再连向两个点即可。

  • 注意开够数组范围。

Code(倍增LCA)

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
const int N=5002,M=105001;
struct data
{int x,y;LL z;
}a[M];
int tot,num;
int first[N],next[N<<1],en[N<<1];
LL w[N<<1];
int f[N],size[N],fa[N][13],dep[N];
LL g[N][13];
template<typename T>inline T read()
{T X=0,w=0; char ch=0;while(ch<'0' || ch>'9') {w|=ch=='-';ch=getchar();}while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+(ch^48),ch=getchar();return w?-X:X;
}
inline LL max(LL x,LL y)
{return x>y?x:y;
}
inline bool cmp(data x,data y)
{return x.z<y.z;
}
inline int get(int x)
{return f[x]==x?x:f[x]=get(f[x]);
}
inline bool merge(int x,int y)
{if(get(x)==get(y)) return false;if(size[f[x]]<size[f[y]]) swap(x,y);size[f[x]]+=size[f[y]];f[f[y]]=x;return true;
}
inline void insert(int x,int y,LL z)
{next[++tot]=first[x];first[x]=tot;en[tot]=y;w[tot]=z;
}
inline void dfs(int x)
{dep[x]=dep[fa[x][0]]+1;for(int i=first[x];i;i=next[i])if(en[i]^fa[x][0]){fa[en[i]][0]=x;g[en[i]][0]=w[i];dfs(en[i]);}
}
inline LL lca(int x,int y)
{if(dep[x]<dep[y]) swap(x,y);LL mx=0;for(int i=log2(dep[x]);i>=0;i--)if(dep[fa[x][i]]>=dep[y]){mx=max(mx,g[x][i]);x=fa[x][i];}if(x==y) return mx;for(int i=log2(dep[x]);i>=0;i--)if(fa[x][i]!=fa[y][i]){mx=max(mx,max(g[x][i],g[y][i]));x=fa[x][i],y=fa[y][i];}mx=max(mx,max(g[x][0],g[y][0]));return mx;
}
int main()
{int n=read<int>(),m=read<int>(),k=read<int>();for(int i=1;i<=m;i++)a[i].x=read<int>(),a[i].y=read<int>(),a[i].z=read<LL>();sort(a+1,a+1+m,cmp);for(int i=1;i<=n;i++) size[f[i]=i]=1;for(int i=1,k=1;i<=m;i++)if(merge(a[i].x,a[i].y)){insert(a[i].x,a[i].y,a[i].z);insert(a[i].y,a[i].x,a[i].z);a[++num]=a[i];if(++k==n) break;}dfs(1);for(int j=1,p=log2(n);j<=p;j++)for(int i=1;i<=n;i++){fa[i][j]=fa[fa[i][j-1]][j-1];g[i][j]=max(g[fa[i][j-1]][j-1],g[i][j-1]);}int q=read<int>();while(q--){char ch=getchar();while(ch!='g' && ch!='a') ch=getchar();if(ch=='g'){LL ans=0;for(int i=1;i<=k;i++) ans^=lca(read<int>(),read<int>());if(ans) puts("madoka"); else puts("Baozika");}else{int x=read<int>(),y=read<int>();LL z=read<LL>();if(lca(x,y)<=z) continue;tot=fa[1][0]=0;memset(first,0,sizeof(first));memset(g,0,sizeof(g));//a[++num]=(data){x,y,z};//sort(a+1,a+1+num,cmp);bool pd=true;for(int i=1;i<=num;i++)if(z<=a[i].z){for(int j=++num;j>i;j--) a[j]=a[j-1];a[i]=(data){x,y,z};pd=false;break;}if(pd) a[++num]=(data){x,y,z};for(int i=1;i<=n;i++) size[f[i]=i]=1;num=0;for(int i=1,k=1;i<=n;i++)if(merge(a[i].x,a[i].y)){insert(a[i].x,a[i].y,a[i].z);insert(a[i].y,a[i].x,a[i].z);a[++num]=a[i];if(++k==n) break;}dfs(1);for(int j=1,p=log2(n);j<=p;j++)for(int i=1;i<=n;i++){fa[i][j]=fa[fa[i][j-1]][j-1];g[i][j]=max(g[fa[i][j-1]][j-1],g[i][j-1]);}}}return 0;
}

Code(Link-Cut-Tree)

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
using namespace std;
typedef long long LL;
const int N=110005;
struct data
{int x,y;
}a[N];
int tot,top;
int fa[N],s[N][2],mx[N],st[N];
LL key[N];
bool rev[N];
template<typename T>inline T read()
{T X=0,w=0; char ch=0;while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();return w?-X:X;
}
inline bool pd(int x)
{return x==s[fa[x]][1];
}
inline bool isroot(int x)
{return s[fa[x]][0]^x && s[fa[x]][1]^x;
}
inline void modify(int x)
{if(x) swap(s[x][0],s[x][1]),rev[x]^=1;
}
inline void update(int x)
{mx[x]=key[mx[s[x][0]]]>key[mx[s[x][1]]]?mx[s[x][0]]:mx[s[x][1]];if(key[x]>key[mx[x]]) mx[x]=x;
}
inline void down(int x)
{if(rev[x]){modify(s[x][0]),modify(s[x][1]);rev[x]=false;}
}
inline void rotate(int x)
{int y=fa[x],w=pd(x);if(s[y][w]=s[x][w^1]) fa[s[x][w^1]]=y;if((fa[x]=fa[y]) && !isroot(y)) s[fa[y]][pd(y)]=x;s[fa[y]=x][w^1]=y;update(y);
}
inline void splay(int x)
{for(int y=st[top=1]=x;!isroot(y);y=fa[y]) st[++top]=fa[y];while(top) down(st[top--]);for(int y;!isroot(x);rotate(x))if(!isroot(y=fa[x])) rotate(pd(x)==pd(y)?y:x);update(x);
}
inline void access(int x)
{for(int y=0;x;x=fa[y=x]) splay(x),s[x][1]=y,update(x);
}
inline void mkroot(int x)
{access(x),splay(x),modify(x);
}
inline void link(int x,int y)
{mkroot(x),fa[x]=y;
}
inline void cut(int x,int y)
{mkroot(x),access(y),splay(y);fa[x]=s[y][0]=0;
}
inline int get(int x)
{access(x),splay(x);int y=x;while(s[y][0]) y=s[y][0];return y;
}
int main()
{int n=tot=read<int>(),m=read<int>(),k=read<int>();for(int i=1;i<=m;i++){int x=read<int>(),y=read<int>();LL z=read<LL>();a[i]=(data){x,y};key[mx[++tot]=tot]=z;if(get(x)^get(y)) link(tot,x),link(tot,y); else{mkroot(x),access(y),splay(y);int del=mx[y];if(z<key[del]){cut(del,a[del-n].x),cut(del,a[del-n].y);link(tot,x),link(tot,y);}}}int q=read<int>();while(q--){char ch=getchar();while(ch^'g' && ch^'d') ch=getchar();if(ch=='g'){LL ans=0;for(int i=1;i<=k;i++){int x=read<int>(),y=read<int>();mkroot(x),access(y),splay(y);ans^=key[mx[y]];}puts(ans?"madoka":"Baozika");}else{int x=read<int>(),y=read<int>();LL z=read<LL>();a[++m]=(data){x,y};key[mx[++tot]=tot]=z;if(get(x)^get(y)) link(tot,x),link(tot,y); else{mkroot(x),access(y),splay(y);int del=mx[y];if(z<key[del]){cut(del,a[del-n].x),cut(del,a[del-n].y);link(tot,x),link(tot,y);}}}}return 0;
}

JZOJ 5466. 【NOIP2017提高A组冲刺11.9】玩游戏相关推荐

  1. JZOJ 5441. 【NOIP2017提高A组冲刺11.1】序列

    Description 给定一个1~n的排列x,每次你可以将x1~xi翻转.你需要求出将序列变为升序的最小操作次数.有多组数据. Input 第一行一个整数t表示数据组数. 每组数据第一行一个整数n, ...

  2. JZOJ 5458. 【NOIP2017提高A组冲刺11.7】质数

    Description 小X 是一位热爱数学的男孩子,在茫茫的数字中,他对质数更有一种独特的情感.小X 认为,质数是一切自然数起源的地方. 在小X 的认知里,质数是除了本身和1 以外,没有其他因数的数 ...

  3. JZOJ 5455. 【NOIP2017提高A组冲刺11.6】拆网线

    Description 企鹅国的网吧们之间由网线互相连接,形成一棵树的结构.现在由于冬天到了,供暖部门缺少燃料,于是他们决定去拆一些网线来做燃料.但是现在有K只企鹅要上网和别人联机游戏,所以他们需要把 ...

  4. JZOJ 5445. 【NOIP2017提高A组冲刺11.2】失格

    Description 胆小鬼连幸福都会害怕,碰到棉花都会受伤,有时还被幸福所伤. --太宰治<人间失格> 回顾我的一生,一共有n个事件,每一个事件有一个幸福值p_i. 我想用n-1条线把 ...

  5. JZOJ 5462. 【NOIP2017提高A组冲刺11.8】好文章

    Description nodgd写了一篇文章,自认为这是一篇好文章.nodgd的文章由n个小写英文字母组成.文章的一个子串指的是文章中的一段连续的字母,子串的长度就是这一段的字母个数.nodgd在文 ...

  6. JZOJ 5463. 【NOIP2017提高A组冲刺11.8】证书

    Description Pulumi生活在P城的角落,而他的朋友们gjdy,oyski,tutuwai等等生活在P城的靠中心位置. P城很大,但它拥有优秀的城市结构,同时P城重视文化教育的发展,P城共 ...

  7. JZOJ 5460. 【NOIP2017提高A组冲刺11.7】士兵训练

    Description Input 第一行两个数n,q 表示士兵数以及阅兵次数. 接下来一行n-1 个整数,第i 个整数表示士兵i+1 的直属教官. 接下来n 行每行两个整数i i b ,l 描述一位 ...

  8. JZOJ 5459. 【NOIP2017提高A组冲刺11.7】密室

    Description 小X 正困在一个密室里,他希望尽快逃出密室. 密室中有N 个房间,初始时,小X 在1 号房间,而出口在N 号房间. 密室的每一个房间中可能有着一些钥匙和一些传送门,一个传送门会 ...

  9. JZOJ 5454. 【NOIP2017提高A组冲刺11.5】仔细的检查

    Description nodgd家里种了一棵树,有一天nodgd比较无聊,就把这棵树画在了一张纸上.另一天nodgd更无聊,就又画了一张. 这时nodgd发现,两次画的顺序是不一样的,这就导致了原本 ...

最新文章

  1. 迷宫出路代码_如何在软件开发的迷宫中找到自己的出路
  2. 关于接口 RandomAccess
  3. Refactor?or Patching?
  4. Windows平台下 找回已丢失的MySql root 用户密码
  5. 【Python学习】 - sklearn学习 - 自带数据集sklearn.datasets.x
  6. 14岁的男孩说想学生信,应该给予哪些指导?
  7. kmemleak的使用
  8. 30. 价格区间设置
  9. 【问题解决】c.a.c.n.c.NacosPropertySourceBuilder : parse data from Nacos error,dataId:xxxxxx.yml
  10. 开心消消乐游戏网页设计作品 学生dreamweaver作业静态HTML网页设计模板 游戏主题网页作业制作
  11. shapefile文件格式说明
  12. 互联网老辛2022年3月上旬社群精华
  13. C语言————鸡兔共有30只,脚共有90只,下面的程序段是计算鸡和兔共有多少只?
  14. 原来在Android中请求权限也可以有这么棒的用户体验(转自郭霖)
  15. # 天下武功无坚不破,唯快不破!
  16. 【转】十大顶级奢侈品服装品牌
  17. 国内首家中高端自由职业者共享平台——易分之一,即将上线运营
  18. 人员规范操作行为识别算法
  19. java部分基础知识 (二):计算机组成原理 原码 补码 反码 按位符 移位符 按位与 按位或 按位抑或 非 分析hashMap的put方法原理
  20. 小猪佩奇源码码,用Python写一个小猪佩奇

热门文章

  1. 转载:matlab 字符串和变量名互换
  2. 时频分析:短时傅里叶变换应用
  3. 有关ucosii中OSTCBY、OSTCBBitY、OSTCBX、OSTCBBitX的意义(我是菜鸟)
  4. leetcode_add_two_numbers
  5. 【算法】ROI Align 原理
  6. [云炬创业管理笔记]第一章讨论3
  7. [一维粒子模拟 version3.6]成功实现初次诊断函数
  8. Feed43自定义 RSS 订阅源
  9. 机器学习碎碎念:霍夫丁不等式
  10. yolov3安卓实现_重磅!MobileNet-YOLOv3来了(含三种框架开源代码)