Codeforces 题面传送门 & 洛谷题面传送门

首先思考一个非常简单的性质:记 \(d=\gcd(n,m)\),那么每次在一起吃完饭的男女孩编号必定与 \(d\) 同余,而根据斐蜀定理可以得到另一方面的结论:对于每一个 \(\bmod d\) 的剩余类,如果其中至少有一个男孩/女孩是快乐的,那所有与这样的男孩/女孩编号 \(\bmod d\) 同余的男孩/女孩最终都会变得快乐。

这样 \(-1\) 的情况就很好判断了:只要检查每个 \(\bmod d\) 的剩余类都至少有一个男孩/女孩是快乐的即可,特别地,如果 \(d>b+g\) 那答案肯定是 \(-1\),而显然要解决答案不是 \(-1\) 的情况,只需要对每个 \(\bmod d\) 的剩余类 \(x\) 都做一遍 \(n,m\) 的互质的情况,设其答案为 \(ans\),然后令答案对 \(ans\times d+x\) 取 \(\max\) 即可。

考虑如何解决 \(n,m\) 互质的情况,考虑同余最短路(怎么想到的/bx,实是神仙),我们考虑这样建图:

  • 对于每个快乐的男孩 \(b\),连一条 \(S\to b\),权值为 \(b\) 的边。
  • 对于每个快乐的女孩 \(g\),连一条 \(S\to g\bmod n\),权值为 \(g\) 的边,表示这个女孩 \(g\) 最早会在 \(g\) 时刻带动男孩 \(g\bmod n\) 变得快乐。
  • 对于每个男孩 \(i\),连边 \(i\to(i+m)\bmod n\),权值为 \(m\),表示如果 \(i\) 变得快乐,那么 \(m\) 时间以后 \((i+m)\bmod n\) 也会变得快乐。

跑最短路即可,最后我们取源点到所有一开始不快乐的男孩距离的最大值,就是所有男孩变得快乐的时间的最大值,然后再对所有女孩做一遍同样的操作即可。

直接建图跑 dijkstra 复杂度是 \(n\log n\) 的,无法通过。我们发现第三类边构成了一个环,因此这个模型可以视作一个环上加了一些源点连到环上某个点的边,要求源点到所有非关键点的距离最大值,而关键点个数很小,因此我们考虑将关键点压进一个 set,然后对于两个相邻关键点 \(l,r\) 路径上的所有点,显然到源点距离最大的肯定是 \(r-1\),因此我们 \(\mathcal O(k)\) 地算出所有这样的 \(r-1\) 到源点的距离,然后取 \(\max\) 即可,这样复杂度就降到了 \(k\log k\),其中 \(k\) 为关键点个数。

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #define fi first
  4. #define se second
  5. #define fill0(a) memset(a,0,sizeof(a))
  6. #define fill1(a) memset(a,-1,sizeof(a))
  7. #define fillbig(a) memset(a,63,sizeof(a))
  8. #define pb push_back
  9. #define ppb pop_back
  10. #define mp make_pair
  11. #define mt make_tuple
  12. #define eprintf(...) fprintf(stderr,__VA_ARGS__)
  13. template<typename T1,typename T2> void chkmin(T1 &x,T2 y){if(x>y) x=y;}
  14. template<typename T1,typename T2> void chkmax(T1 &x,T2 y){if(x<y) x=y;}
  15. typedef pair<int,int> pii;
  16. typedef long long ll;
  17. typedef unsigned int u32;
  18. typedef unsigned long long u64;
  19. typedef long double ld;
  20. namespace fastio{
  21. #define FILE_SIZE 1<<23
  22. char rbuf[FILE_SIZE],*p1=rbuf,*p2=rbuf,wbuf[FILE_SIZE],*p3=wbuf;
  23. inline char getc(){return p1==p2&&(p2=(p1=rbuf)+fread(rbuf,1,FILE_SIZE,stdin),p1==p2)?-1:*p1++;}
  24. inline void putc(char x){(*p3++=x);}
  25. template<typename T> void read(T &x){
  26. x=0;char c=getchar();T neg=0;
  27. while(!isdigit(c)) neg|=!(c^'-'),c=getchar();
  28. while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
  29. if(neg) x=(~x)+1;
  30. }
  31. template<typename T> void recursive_print(T x){return (!x)?void():(recursive_print(x/10),putc(x%10^48),void());}
  32. template<typename T> void print(T x){(!x)&&(putc('0'),0);(x<0)&&(putc('-'),x=~x+1);recursive_print(x);}
  33. template<typename T> void print(T x,char c){print(x);putc(c);}
  34. void print_final(){fwrite(wbuf,1,p3-wbuf,stdout);}
  35. }
  36. const int MAXN=2e5;
  37. const ll INFll=0x3f3f3f3f3f3f3f3fll;
  38. int n,m,B,G,N,M;
  39. vector<int> b[MAXN+5],g[MAXN+5];
  40. int gcd(int x,int y){return (!y)?x:gcd(y,x%y);}
  41. void exgcd(int x,int y,int &a,int &b){
  42. if(!y) return a=1,b=0,void();exgcd(y,x%y,a,b);
  43. int tmp=a;a=b;b=tmp-(x/y)*b;
  44. }
  45. int getinv(int a,int mod){
  46. int x,y;exgcd(a,mod,x,y);
  47. return (x+mod)%mod;
  48. }
  49. ll solve(vector<int> &b,vector<int> &g,int n,int m){
  50. map<int,bool> in;map<int,int> dis;set<int> pos;
  51. for(int x:b){in[x]=1;pos.insert(x);dis[x]=x;}
  52. for(int x:g){
  53. pos.insert(x%n);
  54. if(!dis.count(x%n)) dis[x%n]=x%n;
  55. else chkmin(dis[x%n],x%n);
  56. } int iv=getinv(m,n);
  57. vector<pair<int,pii> > vec;int pos0=(*pos.begin());
  58. for(int p:pos) vec.pb(mp(1ll*(p-pos0)*iv%n,mp(dis[p],in[p])));
  59. vec.pb(mp(n,mp(0,1)));sort(vec.begin(),vec.end());ll mx=-1;
  60. // for(int i=0;i<vec.size();i++) printf("%d %d %d\n",vec[i].fi,vec[i].se.fi,vec[i].se.se);
  61. // printf("\n");
  62. for(int i=1;i<vec.size();i++) if(!vec[i-1].se.se||vec[i].fi!=vec[i-1].fi+1)
  63. chkmax(mx,1ll*(vec[i].fi-vec[i-1].fi-1)*m+vec[i-1].se.fi);
  64. // printf("%d\n",mx);
  65. return mx;
  66. }
  67. int main(){
  68. scanf("%d%d",&n,&m);int d=gcd(n,m);N=n/d;M=m/d;
  69. if(d>MAXN) return puts("-1"),0;
  70. scanf("%d",&B);for(int i=1,x;i<=B;i++) scanf("%d",&x),b[x%d].pb(x/d);
  71. scanf("%d",&G);for(int i=1,x;i<=G;i++) scanf("%d",&x),g[x%d].pb(x/d);
  72. for(int i=0;i<d;i++) if(b[i].empty()&&g[i].empty()) return puts("-1"),0;
  73. ll res=0;
  74. for(int i=0;i<d;i++){
  75. chkmax(res,1ll*d*solve(b[i],g[i],N,M)+i);
  76. chkmax(res,1ll*d*solve(g[i],b[i],M,N)+i);
  77. } printf("%lld\n",res);
  78. return 0;
  79. }

Codeforces 516E - Drazil and His Happy Friends(同余最短路)的更多相关文章

  1. Codeforces 986F - Oppa Funcan Style Remastered(同余最短路)

    Codeforces 题面传送门 & 洛谷题面传送门 感谢此题教会我一个东西叫做同余最短路(大雾 首先这个不同 \(k\) 的个数 \(\le 50\) 这个条件显然是让我们对每个 \(k\) ...

  2. CodeForces - 516B Drazil and Tiles(bfs)

    https://vjudge.net/problem/CodeForces-516B 题意 在一个n*m图中放1*2或者2*1的长方形,问是否存在唯一的方法填满图中的‘.’ 分析 如果要有唯一的方案, ...

  3. CodeForces 515C. Drazil and Factorial

    C. Drazil and Factorial time limit per test 2 seconds memory limit per test 256 megabytes input stan ...

  4. CodeForces 515B. Drazil and His Happy Friends

    B. Drazil and His Happy Friends time limit per test 2 seconds memory limit per test 256 megabytes in ...

  5. codeforces 515C. Drazil and Factorial 解题报告

    题目链接:http://codeforces.com/problemset/problem/515/C 题目意思:给出含有 n 个只有阿拉伯数字的字符串a(可能会有前导0),设定函数F(a) = 每个 ...

  6. codeforces 515A.Drazil and Date 解题报告

    题目链接:http://codeforces.com/problemset/problem/515/A 题目意思:问能否从 (0, 0) 出发,恰好走 s 步,到达该位置(a, b). 首先容易知道, ...

  7. codeforces 515B. Drazil and His Happy Friends 解题报告

    题目链接:http://codeforces.com/problemset/problem/515/B 题目意思:有 n 个 boy 和 m 个 girl,有 b 个 boy 和 g 个 girl ( ...

  8. CodeForces 516C Drazil and Park 线段树

    原文链接http://www.cnblogs.com/zhouzhendong/p/8990745.html 题目传送门 - CodeForces 516C 题意 在一个环上,有$n$棵树. 给出每一 ...

  9. CodeForces 516B Drazil and Tiles 其他

    原文链接http://www.cnblogs.com/zhouzhendong/p/8990658.html 题目传送门 - CodeForces 516B 题意 给出一个$n\times m$的矩形 ...

随机推荐

  1. JavaScript04

    分离绑定事件 使用分离方式绑定元素事件可以使用页面元素与JavaScript代码完全分离,有利于代码分工和维护,是目前开发主流,分为两步: 1.获取需要绑定事件的元素 语法:根据id属性值取元素节点 ...

  2. 关于java socket中的read方法阻塞问题

    客户端: public class TCPClient { public static void main(String[] args) throws IOException { FileInputS ...

  3. 第五课第四周笔记3:Multi-Head Attention多头注意力

    Multi-Head Attention多头注意力 让我们进入并了解多头注意力机制. 符号变得有点复杂,但要记住的事情基本上只是你在上一个视频中学到的自我注意机制的四个大循环. 让我们看一下每次计算自 ...

  4. AIApe问答机器人Scrum Meeting 5.1

    Scrum Meeting 5 日期:2021年5月1日 会议主要内容概述:汇报两日工作. 一.进度情况 组员 负责 两日内已完成的工作 后两日计划完成的工作 工作中遇到的困难 李明昕 后端 Task ...

  5. Photoshop教程,视频MP4格式转换为GIF格式

    转自百度问题 https://zhidao.baidu.com/question/1497485136643778259.html Adobe PhotoShop软件的最bai新du本是可以编辑视zh ...

  6. c语言编程基础入门必备知识

    数据类型 基本数据类型 类型名称说明char字符类型存放字符的ASCII码int整型存放有符号整数short短整型存放有符号整数long长整型存放有符号整数long long存放有符号整数float单 ...

  7. 数列极限计算中运用皮亚诺Taylor展开巧解

    这是讲义里比较精华的几个题目,今晚翻看也是想到了,总结出来(处理k/n2形式). 推广式子如下: 例题如下:

  8. 攻防世界 杂项 1.base64÷4

    666C61677B45333342374644384133423834314341393639394544444241323442363041417D 根据题目base64÷4得base16 在线工 ...

  9. PCIE学习链接集合

    <PCIE基础知识+vivado IP core设置> https://blog.csdn.net/eagle217/article/details/81736822 <一步一步开始 ...

  10. HTML基础-3

    图像标签(<img>)和源属性(Src) 在 HTML 中,图像由 <img> 标签定义. <img> 是空标签,意思是说,它只包含属性,并且没有闭合标签. 要在页 ...