列表

详情


NC233513. Distinct Multiples

描述

给两个数n,m和一个序列D

求满足以下条件的序列A的方案数
-
-
- A_iD_i的倍数

输入描述

第一行两个数

接下来一行包含N个整数

输出描述

输出一个整数表示答案。

示例1

输入:

3 7
2 3 4

输出:

3

示例2

输入:

3 3
1 2 2

输出:

0

示例3

输入:

6 1000000000000000000
380214083 420492929 929717250 666796775 209977152 770361643

输出:

325683519

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 151ms, 内存消耗: 1400K, 提交时间: 2022-03-22 18:36:09

#include<bits/stdc++.h>
#define ll long long
#define PII pair<int,int>
using namespace std;
template<class T> 
inline void read(T &x){ 
	x=0; char c; int sign=1; 
	do{ c=getchar(); if(c=='-') sign=-1;}while(!isdigit(c)); 
	do{ x=x*10+c-'0',c=getchar();}while(isdigit(c)); 
	x*=sign; 
} 
const int N=5e5+50,mod=998244353;
ll gcd(ll a,ll b){
	return b?gcd(b,a%b):a;
}
int n,m,bin[N],h[N],dp[N];
ll M,d[30],lc[N];
int main(){
	read(n),read(M);
	m=1<<n;
	h[1]=1;
	for(int i=0;i<n;++i) read(d[i]),lc[1<<i]=d[i];
	for(int i=1;i<m;++i) bin[i]=bin[i>>1]+(i&1);
	for(int i=2;i<=n;++i) h[i]=1LL*(mod-i+1)*h[i-1]%mod;
	for(int i=1;i<m;++i){
		if(bin[i]==1) continue;
		int j=i&-i;
		if(lc[i-j]==-1) lc[i]=-1;
		else{
			ll t=gcd(lc[i-j],lc[j]);
			ll t1=lc[j]/t;
			if(lc[i-j]>M/t1) lc[i]=-1;
			else lc[i]=lc[i-j]*t1;
		}
	}
	for(int i=1;i<m;++i){
		if(lc[i]==-1) lc[i]=0;
		else lc[i]=M/lc[i]%mod;
		lc[i]=lc[i]*h[bin[i]]%mod;
		//cout<<lc[i]<<endl;
	}
	
	dp[0]=1;
	for(int i=1;i<m;++i){
		int k=i&-i;
		for(int j=i;j>0;j=(j-1)&i) if(j&k)
		dp[i]=(dp[i]+ lc[j]*dp[i^j]%mod )%mod;
	}
	cout<<dp[m-1];
	return 0;
}

C++(g++ 7.5.0) 解法, 执行用时: 384ms, 内存消耗: 1188K, 提交时间: 2022-08-19 17:37:16

#include<bits/stdc++.h>
using namespace std ;
#define ll long long
const int mod = 998244353 ;
const int N = 150000 ;
int n ;
ll m,d[N] ;
int f[N],g[N],h[N],b[N] ;
ll gcd(ll a,ll b)
{
	return b?gcd(b,a%b):a ;
}
ll LCM(ll a,ll b)
{
	ll d=gcd(a,b) ;
	if((__int128)a*b/d>m) return m+1 ;
	else return (__int128)a*b/d ;
}
int main()
{
	scanf("%d%lld",&n,&m) ;
	for(int i=0;i<n;++i) scanf("%lld",&d[i]) ;
	b[0]=0 ;
	for(int i=1;i<(1<<n);++i) b[i]=b[i>>1]+(i&1) ;
	h[1]=1 ;
	for(int i=2;i<=n;++i) h[i]=(mod-i+1ll)*h[i-1]%mod ;
	g[0]=m ;
	for(int i=1;i<(1<<n);++i)
	{
		ll lcm=1 ;
		for(int j=0;j<n;j++) if(i>>j&1)
		{
			lcm=LCM(lcm,d[j]) ;
			g[i]=m/lcm ;
		}
	}
	f[0]=1 ;
	for(int i=1;i<(1<<n);++i)
	{
		int x=i&-i ;
		for(int j=i;j;j=(j-1)&i) if(j&x)
			f[i]=(f[i]+(ll)f[i^j]*g[j]%mod*h[b[j]]%mod)%mod ;
	}
	printf("%d\n",f[(1<<n)-1]) ;
	return 0 ;
}

上一题