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;
}