Count Triples

发布时间 2023-08-11 11:17:06作者: Kreap

枚举约数,多重背包

#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]);
}