首先我们分析怎么样判断是否有解。
设
x
x
x是一个高兴的男生,当他与一个不高兴的女生
y
y
y配对时,
y
y
y将变得高兴。而
x
x
x将在
n
n
n天之后使得女生
y
+
n
m
o
d
  
m
y+n\mod m
y+nmodm高兴,同时
y
y
y也将在
m
m
m天之后使得男生
x
+
m
m
o
d
  
n
x+m\mod n
x+mmodn高兴。所以若某个男生
x
x
x高兴,则在足够多天之后
x
+
i
(
m
,
n
)
m
o
d
  
n
x+i(m,n)\mod n
x+i(m,n)modn的男生和
x
+
i
(
m
,
n
)
m
o
d
  
m
x+i(m,n)\mod m
x+i(m,n)modm的女生都将高兴,所以我们将位置按模
(
m
,
n
)
(m,n)
(m,n)来分组,只要每一组内有至少一个位置高兴,则这个组最终都会高兴。由此,我们得到一个有效剔除无解情况的办法:当
a
+
b
<
(
n
,
m
)
a+b<(n,m)
a+b<(n,m)时必然无解,因为至少会有一组位置没有任何人高兴。
容易想到有解时答案就是每一组位置全员高兴的时间的最大值。考虑用最短路求解。
由之前的分析,我们知道:
若男生
x
x
x一开始就高兴,则女生
x
m
o
d
  
m
x\mod m
xmodm将在第
x
x
x天高兴;
若男生
x
x
x高兴,则
x
+
m
m
o
d
  
n
x+m\mod n
x+mmodn在
m
m
m天之后将会高兴。
我们为男生
x
x
x和
x
+
m
m
o
d
  
n
x+m\mod n
x+mmodn连权为
m
m
m的有向边,为男生
x
x
x和女生
x
m
o
d
  
m
x\mod m
xmodm连权为
0
0
0的有向边,为新建点
p
p
p与
x
x
x连边权为
x
x
x的有向边。
注意到男生和女生各自形成了一个有向环,同时其中的一些点与另一个环上的一些点相连。因为我们需要求最短路的最大值,可以发现对于在环上相邻的一对初始高兴的点(设方向是
x
→
y
x\rightarrow y
x→y)之间,可能的最大值只可能存在于点
y
−
m
m
o
d
  
n
y-m\mod n
y−mmodn,这使得节点数可以降低到
O
(
a
+
b
)
O(a+b)
O(a+b)。故我们用扩展欧几里得求出环上的初始点的顺序和边权,跑一下最短路即可。
#include<algorithm>
#include<iostream>
#include<cstring>
#include<climits>
#include<cstdio>
using namespace std;
#define clr(a) memset(a,0,sizeof(a))
//--Container
#include<queue>
#include<vector>
#include<unordered_set>
#include<unordered_map>
//--
typedef long long ll;
typedef pair<int,int> pi;
const int ups=2e9;
ll exgcd(ll a,ll b,ll &x,ll &y){
if(!b){x=1,y=0;return a;}
ll g=exgcd(b,a%b,x,y);
ll dx=x,dy=y;x=dy,y=dx-(a/b)*dy;
return g;
};
struct eg{int u,v,nx;ll c;}gp[2000010];int vn,cnt,hd[1000010];
inline void psh(int u,int v,ll c){
++cnt;gp[cnt].u=u,gp[cnt].c=c,gp[cnt].v=v,gp[cnt].nx=hd[u],hd[u]=cnt;
};
int ar[2][100010],br[2],n,m;
vector<int>vr[2][100010];ll qs[2];int cdr[1000010],dx,dg;ll ds[1000010];bool bd[1000010],xd[1000010];
inline ll _ds(int a,int b,int id,int dn){
ll rs=qs[id]*((b%dn-a%dn+dn)/dg)%dn;rs%=((ll)n*m/dg/(!id?n:m));
return rs;
};
bool bmp0(int a,int b){
ll da=_ds(dx,a,1,n),db=_ds(dx,b,1,n);
return da!=db?da<db:a>b;
};
bool bmp1(int a,int b){
ll da=_ds(dx,a,0,m),db=_ds(dx,b,0,m);
return da!=db?da<db:a>b;
};
unordered_map<int,int>mp[2];
int _id(int x,int d){
if(mp[d].find(x)!=mp[d].end())return mp[d][x];
mp[d][x]=++vn;return vn;
};
ll spfa(){
int i,j,k,d,t;queue<int>qe;for(i=1;i<=vn;++i)bd[i]=0,ds[i]=LLONG_MAX;
for(ds[1]=0,qe.push(1);!qe.empty();){
t=qe.front();qe.pop();bd[t]=0;for(i=hd[t];i;i=gp[i].nx)if(ds[gp[i].v]>ds[t]+gp[i].c){
ds[gp[i].v]=ds[t]+gp[i].c;
if(!bd[gp[i].v])bd[gp[i].v]=1,qe.push(gp[i].v);
}
}
ll rs=0;for(i=1;i<=vn;++i)if(!xd[i])rs=max(rs,ds[i]);
return rs;
};
int __cl(int g,int a,int n){
unordered_set<int>st;int i,j,k,d,t;for(i=d=0;i<vr[a][g].size();++i)
cdr[d++]=vr[a][g][i],st.insert(vr[a][g][i]);
for(i=0;i<vr[a^1][g].size();++i){
if(st.find(vr[a^1][g][i]%n)!=st.end())continue;
st.insert(vr[a^1][g][i]%n);cdr[d++]=vr[a^1][g][i];
}
return d;
};
ll _cl(int g){
int i,j,k,d,t;ll rs=0;
if(vr[0][g].empty()&&vr[1][g].empty())return -1;
d=__cl(g,0,n);vn=1;for(i=0;i<d;++i){t=_id(cdr[i]%n,0);if(i<vr[0][g].size())xd[t]=1;}
dx=cdr[0];sort(cdr,cdr+d,bmp0);
for(i=0;i<d;++i){
int a=cdr[i]%n,b=(cdr[(i+1)%d]%n-m%n+n)%n;
int ad=_id(a,0),bd=_id(b,0);psh(1,ad,cdr[i]);
if(ad!=bd)psh(ad,bd,_ds(a,b,1,n)*m);
bd=_id(cdr[(i+1)%d]%n,0);
psh(ad,bd,_ds(a,cdr[(i+1)%d]%n,1,n)*m);
if(!xd[ad])continue;
bd=_id(a%m,1);psh(ad,bd,0);
}
d=__cl(g,1,m);for(i=0;i<d;++i){t=_id(cdr[i]%m,1);if(i<vr[1][g].size())xd[t]=1;}
dx=cdr[0];sort(cdr,cdr+d,bmp1);
for(i=0;i<d;++i){
int a=cdr[i]%m,b=(cdr[(i+1)%d]%m-n%m+m)%m;
int ad=_id(a,1),bd=_id(b,1);psh(1,ad,cdr[i]);
if(ad!=bd)psh(ad,bd,_ds(a,b,0,m)*n);
bd=_id(cdr[(i+1)%d]%m,1);
psh(ad,bd,_ds(a,cdr[(i+1)%d]%m,0,m)*n);
if(!xd[ad])continue;
bd=_id(a%n,0);psh(ad,bd,0);
}
rs=spfa();mp[0].clear(),mp[1].clear();
for(i=1;i<=vn;++i)xd[i]=0,hd[i]=0;vn=cnt=0;
return rs;
};
void cl(){
int i,j,k,d,t;scanf("%d %d",&n,&m);
scanf("%d",&br[0]);for(i=0;i<br[0];scanf("%d",&ar[0][i++]));
scanf("%d",&br[1]);for(i=0;i<br[1];scanf("%d",&ar[1][i++]));
sort(ar[0],ar[0]+br[0]),sort(ar[1],ar[1]+br[1]);
d=exgcd(n,m,qs[0],qs[1]);dg=d;
if(br[0]+br[1]<d){printf("-1\n");return;}
qs[0]=(qs[0]-((qs[0]/m)*m)+m)%m;
qs[1]=(qs[1]-((qs[1]/n)*n)+n)%n;
for(i=0;i<br[0];++i)vr[0][ar[0][i]%d].push_back(ar[0][i]);
for(i=0;i<br[1];++i)vr[1][ar[1][i]%d].push_back(ar[1][i]);
ll rs=0;for(i=0;i<dg;++i){
ll zt=_cl(i);if(zt<0){rs=-1;break;}
rs=max(rs,zt);
}
printf("%I64d\n",rs);
};
int main(){
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
cl();
return 0;
};