可以枚举一个(a_i),然后就是求(sum_{x=0}^{lfloorfrac{t-1-a_i}{p} floor}[px+a_i in B(mod q)])
可以发现所有(px+a_imod q)的值是成环的,就可以求出这个环所有前缀中(in B)的元素个数,然后那个式子的值就是完整的环出现次数*环内(B)元素个数+剩下部分的(B)元素个数.并且模(gcd(p,q))同余的(a_i),环内元素构成的集合是一样的,所以可以枚举(d),然后把(a_i =dmod gcd(p,q))的(a_i)放在一起处理
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<vector>
#include<cmath>
#include<ctime>
#include<queue>
#include<map>
#include<set>
#define LL long long
#define db double
using namespace std;
const int N=1e6+10;
LL rd()
{
LL x=0,w=1;char ch=0;
while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*w;
}
LL mi[N],p,q,d,lcm,n,m,a[N],b[N],t,ans,s[N<<1],ps[N];
bool v[N];
int gcd(int a,int b){return b?gcd(b,a%b):a;}
bool cmp(int aa,int bb){return aa%d<bb%d;}
int main()
{
memset(mi,0x3f,sizeof(mi));
p=rd(),q=rd(),n=rd(),m=rd(),t=rd()-1;
for(int i=1;i<=n;++i) a[i]=rd();
for(int i=1;i<=m;++i) b[i]=rd();
if(p>q)
{
swap(p,q),swap(n,m);
for(int i=1;i<=n||i<=m;++i) swap(a[i],b[i]);
}
for(int i=1;i<=m;++i) v[b[i]]=1;
d=gcd(p,q),lcm=p/d*q;
sort(a+1,a+n+1,cmp);
for(int i=0,j=1;i<d;++i)
{
LL lm=q/d;
for(int k=1,l=i;k<=lm;++k,l=(l+p)%q)
s[k]=s[k+lm]=v[l],ps[l]=k;
for(int k=1;k<=lm*2;++k) s[k]+=s[k-1];
while(j<=n&&a[j]%d==i)
{
int ii=ps[a[j]],len=((t-a[j])%lcm+p)/p;
ans+=(t-a[j])/lcm*s[lm]+s[ii+len-1]-s[ii-1];
++j;
}
}
printf("%lld
",ans);
return 0;
}