【莫反】CF900D Unusual Sequences 做题记录
从一个 dp 题单点进去的,往 dp 上想了半天,啥都没想出来,看了个题解,发现可以莫反做,于是重新思考。
先考虑无解的情况,很明显,\(x \nmid y\) 时,是不存在合法的构造的。往简化的方向走,设 \(sum=y \div x\),那么题目可以转化为满足 \(\sum_{i=1}^{n}a_i=sum\) \(\gcd(a_1,a_2,a_3,...,a_n)=1\) 的数列的个数。考虑设 \(g(x)\) 为 \(\sum_{i=1}^{n}a_i=x\) 的个数,考虑使用隔板法求 \(g(x)\):
\[g(x)=\sum_{i=1}^{n}\binom{x-1}{i-1}=2^{x-1}
\]
设 \(f(x)\) 为满足 \(\sum_{i=1}^{n}a_i=x\) \(\gcd(a_1,...,a_n)=1\) 的数列个数,根据反演,\(g(x)=\sum_{d \mid x}f(d)\),那么:
\[f(x)=\sum_{d \mid x}g(\frac{x}{d})\mu(d)
\]
显然,本题答案为 \(f(sum)\)。
\(Code\)
点击查看代码
/*
考虑无解,当y%x!=0时无解
考虑设gcd为1,隔板法求方案数
考虑莫反
容斥是什么神仙做法/fad
线性筛复杂度达到了1e9
似乎会T
考虑求单个
*/
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define mod (int)(1e9+7)
inline int mu(int x){
int prid=0;
int sq=0;
for(int i=2;i*i<=x;++i){
if(x%i) continue;
sq=0;
prid++;
while(x%i==0){x/=i;sq++;}
if(sq>=2) return 0;
}
x==1?:prid++;
return (prid&1)?mod-1:1;
}
inline int qpow(int a,int b){
int res=1;
while(b){
if(b&1) res=res*a%mod;
b>>=1;a=a*a%mod;
}
return res;
}
signed main(){
int x,y,ans=0;
scanf("%lld %lld",&x,&y);
if(y%x) return puts("0"),0;
int n=y/x;
for(int i=1;i*i<=n;++i){
if(!(n%i)){
ans=(ans+qpow(2,i-1)*mu(n/i)%mod)%mod;
if(i*i!=n) ans=(ans+qpow(2,n/i-1)*mu(i)%mod)%mod;
}
}
printf("%lld\n",ans);
return 0;
}

浙公网安备 33010602011771号