给定$n,m$,有$n$个非负整数变量,分别是$x_1,x_2, \dots x_n$,其中$0 \le x_i \le m$
求出满足$\gcd(x_1,x_2, \dots x_n,m)=1$的解的数量
$n \le 15, m \le 10^8$
对$m$进行质因数分解,之后就相当于问$\gcd \ge d$的方案数了,显然是$(\lfloor \frac{m}{d} \rfloor)^n$
直接套上容斥
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 #include <iostream> 2 #include <algorithm> 3 #include <cstdio> 4 #include <cstring> 5 #include <cstdlib> 6 using namespace std; 7 typedef long long ll; 8 9 ll n, m; 10 11 ll pw(ll a, ll b) { 12 ll r = 1; 13 for( ; b ; b >>= 1, a *= a) if(b & 1) r *= a; 14 return r; 15 } 16 17 const int N = 1e7 + 10; 18 ll p[N], tot; 19 20 int main() { 21 cin >> n >> m; 22 ll _m = m; 23 for(ll i = 2 ; i * i <= _m ; ++ i) { 24 if(_m % i) continue; 25 p[++ tot] = i; 26 while(_m % i == 0) _m /= i; 27 } 28 if(_m > 1) p[++ tot] = _m; 29 ll ans = 0; 30 for(int s = 0 ; s < (1 << tot) ; ++ s) { 31 ll lcm = 1, cnt = 0; 32 for(int i = 1 ; i <= tot ; ++ i) { 33 if((s >> (i - 1)) & 1) { 34 lcm *= p[i]; 35 ++ cnt; 36 } 37 } 38 ans += (cnt & 1 ? -1 : 1) * pw(m / lcm, n); 39 } 40 printf("%lld\n", ans); 41 }