Codeforces Round #450 (Div. 2)D. Unusual Sequences

题目连接:D. Unusual Sequences

题解:当y%x0时才有解。把q=y/x的因数找出,用数组p保存, dp[i]表示每一份为p[i]时的分割情况,用隔板法有q/p[i]-1个空可以分成2的q/p[i]-1方
所以dp[i]=2的q/p[i]-1方
然后dp[i]减去容斥的最后dp[0]就是答案,那种是容斥的呢,我们可以发现当p[i]%p[j]
0的时候,dp[i]的方法gcd!=x;所以dp[j]就要减去dp[i]的次数;

#include<bits/stdc++.h>
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#define pb push_back
#define ll long long
#define PI 3.14159265
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define eps 1e-7
const int mod=1e9+7;
const int maxn=1e5+5;
using namespace std;
ll x,y;
int p[maxn];
ll dp[maxn];
ll qpow(ll a,ll b)
{
    ll c=1;
    while(b)
    {
        if(b%2)
        {
            c*=a;
            c%=mod;
        }
        b/=2;
        a=(a*a)%mod;
    }
    return c;
}
int main()
{
    std::ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin>>x>>y;
    if(y%x)
    {
        cout<<0<<endl;
    }
    else
    {
        ll q=y/x;ll t=0;
        for(int i=1;i*i<=q;i++)
        {
            if(q%i==0)
            {
                p[t++]=i;
                if(i*i!=q)p[t++]=q/i;
            }
        }
        sort(p,p+t);
        for(int i=0;i<t;i++)
        {
            dp[i]=qpow(2,q/p[i]-1);
        }
        for(int i=t-1;i>=0;i--)
        {
            for(int j=0;j<i;j++)
            {
                if(p[i]%p[j]==0)
                dp[j]=(dp[j]-dp[i]+mod)%mod;
            }
        }
        cout<<dp[0]<<endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/lhclqslove/p/8261772.html