碰到这种题第一反应就是找循环节.
我们发现我们就是要求 $a[i]+P \times k=b[i] ( \mod Q)$ 中 $P$ 的 k 的个数.
那么对于 $a[i]$ 来说,最大步数为 $\frac{T-1-a[i]}{P}$.
而我们发现 $a[i]+ P \times k$ 的循环节是 $P \times k=0( \mod Q)$,这个循环节是 $lcm(P,Q)$,而 $k$ 的个数就是 $\frac{lcm(P,Q)}{P}$
枚举 $0$ ~ $Q$,然后对于 $i$ 向 $(i+P)%Q$ 连边,一定会形成若干个环长为 $\frac{Q}{gcd(P,Q)}$ 的环.
那么,让每一个 $a[i]$ 在环上走 $\frac{T-1-a[i]}{P}$ 步,算一下点权和即可.
code:
#include <bits/stdc++.h>
#define ll long long
#define N 1000006
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
ll T,ans,p[N];
vector<int>s[N],v[N];
int len,P,Q,n,m,a[N],b[N],tx[N],w[N],col[N],pos[N],num;
int dfs(int x,int c)
{
if(col[x])
return 0;
col[x]=c;
v[col[x]].push_back(x);
return tx[x]+dfs((x+P)%Q,c);
}
int find(int l,int x)
{
return s[col[x]][pos[x]+l]-s[col[x]][pos[x]];
}
int main()
{
// setIO("input");
int i,j;
scanf("%d%d%d%d%lld",&P,&Q,&n,&m,&T);
for(i=1;i<=n;++i)
scanf("%d",&a[i]);
for(i=1;i<=m;++i)
scanf("%d",&b[i]);
if(P>Q)
{
swap(P,Q);
swap(a,b);
swap(n,m);
}
len=Q/__gcd(P,Q);
for(i=1;i<=m;++i)
tx[b[i]]=1;
for(i=1;i<=n;++i)
p[i]=(T-1-a[i])/P;
for(i=0;i<Q;++i)
{
if(!col[i])
++num,w[num]=dfs(i,num);
}
for(i=1;i<=num;++i)
{
for(j=0;j<v[i].size();++j)
pos[v[i][j]]=j;
int t=v[i].size()-1;
for(j=0;j<t;++j)
v[i].push_back(v[i][j]);
s[i].push_back(tx[v[i][0]]);
for(j=1;j<v[i].size();++j)
s[i].push_back(s[i][j-1]+tx[v[i][j]]);
}
for(i=1;i<=n;++i)
{
ans+=(ll)(p[i]/len)*w[col[a[i]]];
ans+=find(p[i]%len,a[i])+tx[a[i]];
}
printf("%lld\n",ans);
return 0;
}