D. Unusual Sequences
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Count the number of distinct sequences a1, a2, …, an (1 ≤ ai) consisting of positive integers such that gcd(a1, a2, …, an) = x and . As this number could be large, print the answer modulo 109 + 7.
gcd here means the greatest common divisor.
Input
The only line contains two positive integers x and y (1 ≤ x, y ≤ 109).
Output
Print the number of such sequences modulo 109 + 7.
Examples
input
3 9
output
3
input
5 8
output
0
题意:构造一个数组,要求每一位大于等于1,所有数的gcd为1,就相当于构造y/x,gcd为1的序列,首先我们可以证明对于n,把它任意的分成一个数组,一共有2^(n-1)种,然后可以知道这些序列的gcd是某一个数a的倍数就是2^(n/a-1)种,然后用莫比乌斯系数容斥就可以得到答案了。因为对于1e9的数据来说,最多只有11个质因数,那么可以用状压处理处需要的莫比乌斯系数的值,然后可以得到答案。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
vector<int> pe;
vector<int> pr;
bool vis[100005];
const int mod = 1e9+7;
int x,y;
ll qpow(int x,int b){
ll now = x;
ll sum =1;
while(b){
if(b&1) sum = sum*now%mod;
now = now*now%mod;
b >>= 1;
}
return sum;
}
void init(){
vis[1] = true;
for(int i = 2;i <= 100005;i ++){
if(vis[i] == false) pe.push_back(i);
for(int j = 0;j < pe.size()&&i*pe[j] < 100005;j ++){
vis[i*pe[j]] = true;
if(i%pe[j] == 0) break;
}
}
int now = x;
for(int i =0;i < pe.size();i ++){
if(now%pe[i] == 0){
pr.push_back(pe[i]);
while(now%pe[i]==0) now /= pe[i];
}
}
if(now != 1) pr.push_back(now);
int res = pr.size();
ll ans = qpow(2,x-1);
for(int i = 1;i < (1<<res);i ++){
int tmp = 1,f = 1;
for(int j = 0;j <res;j ++){
if(i&(1<<j)) tmp *= pr[j],f *= -1;
}
ans = (ans+qpow(2,x/tmp-1)*f+mod)%mod;
}
printf("%lld\n",ans);
}
int main(){
scanf("%d %d",&x,&y);
if(y%x){
puts("0");
return 0;
}
x = y/x;
init();
return 0;
}