我是靠谱客的博主 友好白云,最近开发中收集的这篇文章主要介绍CodeForces 900D-Unusual Sequences(快速幂,莫比乌斯反演)CodeForces 900D-Unusual Sequences,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

CodeForces 900D-Unusual Sequences

题目原址

[http://codeforces.com/problemset/problem/900/D]

题意

有这样的序列 a 1 , a 2 , a 3 ⋅ ⋅ ⋅ a n a_{1},a_{2},a_{3}···a_{n} a1,a2,a3an 使得他们的和为 y y y ,最大公因数为 x x x,问满足这样的序列有多少个。

题解

练习题里的题,我原来根本看不出是莫比乌斯反演。
显然对于每个 a i a_{i} ai 都是 x x x 的倍数,于是 y y y x x x 的倍数。
如果不考虑最大公因数是 x x x 这个条件的话,把每个 a i a_{i} ai 都除以 x x x,就是纯粹的有序整数拆分问题,也就是 2 y x − 1 2^{frac{y}{x}-1} 2xy1
但这显然是 ∑ d ∣ y x [ gcd ⁡ = d ] sum_{d|frac{y}{x}}[gcd=d] dxy[gcd=d] 的情况数,所以我们要去掉 ∑ [ gcd ⁡ ≠ 1 ] sum[gcdneq 1] [gcd̸=1] 的情况,也就是 ∑ d ∣ y x [ gcd ⁡ = d & & d ! = 1 ] sum_{d|frac{y}{x}}[gcd=d && d!=1] dxy[gcd=d&&d!=1] 的情况。
上面是一种思路,另一种思路就是莫比乌斯反演了,如果我们用 f ( n ) f(n) f(n) 表示 ∑ n ∣ y x [ gcd ⁡ = n ] sum_{n|frac{y}{x}}[gcd=n] nxy[gcd=n]
那么我们就是要求 f ( 1 ) f(1) f(1),然后他的倍数和 F ( n ) = ∑ n ∣ d f ( d ) F(n)=sum_{n|d}f(d) F(n)=ndf(d) 就表示 ∑ n ∣ y x [ n ∣ gcd ⁡ ] sum_{n|frac{y}{x}}[n|gcd] nxy[ngcd] 的情况数了,也就是 2 y x n − 1 2^{frac{frac{y}{x}}{n}-1} 2nxy1 种情况,所以我们也直接枚举莫比乌斯函数值不为0的约数就可以了。

代码

#include<iostream>
using namespace std;
typedef long long ll;
const int maxn=1e6+7;
const int mod=1e9+7;
int yue[maxn],numy,n;
ll ans;
ll power(ll a,ll b){
    ll ans=1;
    while(b){
        if(b&1)ans=(ans*a)%mod;
        a=(a*a)%mod;
        b>>=1;
    }
    return ans;
}
void dfs(int len,int mu,ll s){
    if(len>numy){
        ans=((ans+(ll)mu*power(2,n/s-1))%mod+mod)%mod;
        return;
    }
    dfs(len+1,mu,s);
    dfs(len+1,-mu,s*yue[len]);
}
int main(){
    #ifdef LOCAL
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif // LOCAL
    ios::sync_with_stdio(false);
    int x,y;
    while(cin>>x>>y){
        if(y%x){
            cout<<0<<endl;
            continue;
        }
        numy=0;ans=0;
        n=y/x;int tmp=n;
        for(int i=2;i<=n;i++)
            if(n%i==0){
                yue[++numy]=i;
                while(n%i==0)
                    n/=i;
            }
        n=tmp;
        dfs(1,1,1);
        cout<<ans<<endl;
    }
}

最后

以上就是友好白云为你收集整理的CodeForces 900D-Unusual Sequences(快速幂,莫比乌斯反演)CodeForces 900D-Unusual Sequences的全部内容,希望文章能够帮你解决CodeForces 900D-Unusual Sequences(快速幂,莫比乌斯反演)CodeForces 900D-Unusual Sequences所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(38)

评论列表共有 0 条评论

立即
投稿
返回
顶部