//用筛法生成素数 const int MAXN = 1000000; bool arr[MAXN+1] = {false}; vector<int> produce_prim_number() { vector<int> prim; prim.push_back(2); int i,j; for(i=3; i*i<=MAXN; i+=2) { if(!arr[i]) { prim.push_back(i); for(j=i*i; j<=MAXN; j+=i) arr[j] = true; } } while(i<=MAXN) { if(!arr[i]) prim.push_back(i); i+=2; } return prim; } //计算n!中素因子p的指数 int Cal(int x, int p) { int ans = 0; long long rec = p; while(x>=rec) { ans += x/rec; rec *= p; } return ans; } //计算n的k次方对M取模,二分法 int Pow(long long n, int k, int M) { long long ans = 1; while(k) { if(k&1) { ans = (ans * n) % M; } n = (n * n) % M; k >>= 1; } return ans; } //计算C(n,m) int Combination(int n, int m) { const int M = 10007; vector<int> prim = produce_prim_number(); long long ans = 1; int num; for(int i=0; i<prim.size() && prim[i]<=n; ++i) { num = Cal(n, prim[i]) - Cal(m, prim[i]) - Cal(n-m, prim[i]); ans = (ans * Pow(prim[i], num, M)) % M; } return ans; }
LL solve (LL n, LL r) { vector<int> p; for (int i=2; i*i<=n; ++i) if (n % i == 0) { p.push_back (i); while (n % i == 0) n /= i; } if (n > 1) p.push_back (n);
LL sum = 0; for (int msk=1; msk<(1<<p.size()); ++msk) { LL mult = 1, bits = 0; for (int i=0; i<(LL)p.size(); ++i) if (msk & (1<<i)) { ++bits; mult *= p[i]; }
LL cur = r / mult; if (bits % 2 == 1) sum += cur; else sum -= cur; }
int mobius(int n){ int m = 1; for(int i=2;i*i<=n;i++){ if(n%i==0){ m*=-1; int k = 0; n/=i; if(n%i==0) {m=0;break;}//某个素因子的幂大于1 } } if(n>1) m *= -1; return m; }
/*******************************************/ 线性筛法预处理mobius函数 int prime[N],kp; int Is_or[N],mu[N];