HNOI的题。。。蛋疼的没有想到,看了discuss。。。
已知N+1个数,x1, x2, .. xn, m;使得gcd(x1, x2, ..., xn) = 1(mod m)。也就是说gcd(x1, x2,..., xn, m) = 1
需要找x1, x2, ... ,xn这样的序列多少个。其实就是找到与m互素的数构造这个集合就可以。。。
首先对m进行分解质因子,可以用容斥原理找到与m不互素的数构成的集合,用m^n减掉就可以了;
ps:貌似这题不用高精度。
//#pragma comment(linker,"/STACK:327680000,327680000") #include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <cstring> #include <algorithm> #include <string> #include <set> #include <functional> #include <numeric> #include <sstream> #include <stack> #include <map> #include <queue> #define CL(arr, val) memset(arr, val, sizeof(arr)) #define REP(i, n) for((i) = 0; (i) < (n); ++(i)) #define FOR(i, l, h) for((i) = (l); (i) <= (h); ++(i)) #define FORD(i, h, l) for((i) = (h); (i) >= (l); --(i)) #define L(x) (x) << 1 #define R(x) (x) << 1 | 1 #define MID(l, r) (l + r) >> 1 #define Min(x, y) (x) < (y) ? (x) : (y) #define Max(x, y) (x) < (y) ? (y) : (x) #define E(x) (1 << (x)) #define iabs(x) (x) < 0 ? -(x) : (x) #define OUT(x) printf("%I64d\n", x) #define Read() freopen("data.in", "r", stdin) #define Write() freopen("data.out", "w", stdout); typedef long long LL; const double eps = 1e-8; const double pi = acos(-1.0); const double inf = ~0u>>2; using namespace std; const int N = 20010; int prime[N], cnt; bool vis[N]; int p[N], num; void get_prime() { CL(vis, true); int i, j; for(i = 2; i < N; ++i) { for(j = i*i; j < N; j += i) { vis[j] = false; } } cnt = 0; for(i = 2; i < N; ++i) { if(vis[i]) prime[cnt++] = i; } } void get_p(int m) { int i; num = 0; for(i = 0; i < cnt && prime[i] <= m; ++i) { if(m%prime[i] == 0) { p[num++] = prime[i]; while(m%prime[i] == 0) { m /= prime[i]; } } } if(m != 1) p[num++] = m; } LL exp(LL a, LL b) { LL res = 1; while(b--) res *= a; return res; } int main() { //Read(); int n, m, j, bit; get_prime(); while(~scanf("%d%d", &n, &m)) { get_p(m); LL res = 0, sum, i; for(i = 1; i < (1<<num); ++i) { bit = 0; sum = 1; for(j = 0; j< num; ++j) { if(i&(1<<j)) { bit++; sum *= p[j]; } } if(bit&1) res -= exp(m/sum, n); else res += exp(m/sum, n); } LL ans = exp(m, n); //printf("%lld\n", ans); printf("%lld\n", ans + res); } return 0; }