Count Triples
Link
枚举约数,多重背包
#include<stdio.h>
#include<algorithm>
#include<map>
using namespace std;
#define ll long long
inline int read(){
int x=0,flag=1; char c=getchar();
while(c<'0'||c>'9'){if(c=='-') flag=-1; c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
return x*flag;
}
map<int,bool> is;
map<int,ll> mp[4],b,ans;
int p[100000],tp=0;
int main(){
int n=read(),m=read();
for(int i=1;i*i<=m;i++)
if(m%i==0){
p[++tp]=i;
if(i*i!=m) p[++tp]=m/i;
}
sort(p+1,p+1+tp);
for(int i=1;i<=tp;i++) is[p[i]]=1;
for(int o=1;o<=3;o++)
for(int i=1;i<=n;i++){
int x=read();
if(m%x!=0) continue;
mp[o][x]++;
}
for(int f=0;f<=1;f++)
for(int i=1;i<=tp;i++)
for(int j=1;j<=tp;j++){
ll x=1ll*p[i]*p[j];
if(x>m) break;
if(!is[x]) continue;
if(!f) b[x]+=mp[1][p[i]]*mp[2][p[j]];
else ans[x]+=b[p[i]]*mp[3][p[j]];
}
printf("%lld",ans[m]);
}