Easy Math(ACM-ICPC 2018 徐州赛区网络预赛)(递归 + 杜教筛)
Easy Math
推式子
∑i=1mμ(in)∑i=1mμ(i×nd×d),d是n的一個質因子i,d互質項有(?∑i=1mμ(i×nd)),由于減去了多余的非互質項,所以加上,?∑i=1mμ(i×nd)+∑i=1mdμ(i×d×nd)?∑i=1mμ(i×nd)+∑i=1mdμ(i×n)\sum_{i = 1} ^{m} \mu(in)\\ \sum_{i = 1} ^{m} \mu(i \times \frac{n}ze8trgl8bvbq \times d),d是n的一個質因子\\ i, d互質項有(-\sum_{i = 1} ^{m} \mu(i \times \frac{n}ze8trgl8bvbq)),由于減去了多余的非互質項,所以加上,\\ -\sum_{i = 1} ^{m} \mu(i \times \frac{n}ze8trgl8bvbq) + \sum_{i = 1} ^{\frac{m}ze8trgl8bvbq} \mu(i \times d \times \frac{n}ze8trgl8bvbq)\\ -\sum_{i = 1} ^{m} \mu(i \times \frac{n}ze8trgl8bvbq) + \sum_{i = 1} ^{\frac{m}ze8trgl8bvbq} \mu(i \times n)\\ i=1∑m?μ(in)i=1∑m?μ(i×dn?×d),d是n的一個質因子i,d互質項有(?i=1∑m?μ(i×dn?)),由于減去了多余的非互質項,所以加上,?i=1∑m?μ(i×dn?)+i=1∑dm??μ(i×d×dn?)?i=1∑m?μ(i×dn?)+i=1∑dm??μ(i×n)
由此我們可以遞歸加上杜教篩來得到答案:
邊界條件n==1n == 1n==1,return∑i=1mμ(i)return\ \sum_{i = 1} ^{m} \mu(i)return?∑i=1m?μ(i)。
m==0,return0m == 0, return\ 0m==0,return?0。
代碼
/*Author : lifehappy */ #pragma GCC optimize(2) #pragma GCC optimize(3) #include <bits/stdc++.h>using namespace std;typedef long long ll; const int inf = 0x3f3f3f3f;const int N = 2e6 + 10;int prime[N], mu[N], cnt;bool st[N];void init() {mu[1] = 1;for(int i = 2; i < N; i++) {if(!st[i]) {prime[cnt++] = i;mu[i] = -1;}for(int j = 0; j < cnt && 1ll * i * prime[j] < N; j++) {st[i * prime[j]] = 1;if(i % prime[j] == 0) break;mu[i * prime[j]] = -mu[i];}}for(int i = 1; i < N; i++) {mu[i] += mu[i - 1];} }map<ll, ll> ans_s;ll S(ll n) {if(n < N) return mu[n];if(ans_s.count(n)) return ans_s[n];ll ans = 1;for(ll l = 2, r; l <= n; l = r + 1) {r = n / (n / l);ans -= (r - l + 1) * S(n / l);}return ans_s[n] = ans; }ll F(ll n, ll m) {if(n == 1) return S(m);if(m == 0) return 0;for(int i = 0; 1ll * prime[i] * prime[i] <= n; i++) {if(n % prime[i] == 0) {return F(n, m / prime[i]) - F(n / prime[i], m);} }return F(n, m / n) - F(n / n, m); }int main() { // freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); // ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);init();ll n, m;scanf("%lld %lld", &m, &n);ll temp = n; for(int i = 0; i < cnt; i++) {int cnt = 0;while(n % prime[i] == 0) {n /= prime[i];cnt++;}if(cnt >= 2) {puts("0");return 0;}}printf("%lld\n", F(temp, m));return 0; }總結
以上是生活随笔為你收集整理的Easy Math(ACM-ICPC 2018 徐州赛区网络预赛)(递归 + 杜教筛)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 喝冰美式咖啡可以减肥吗
- 下一篇: Convex Hull (ACM-ICP