NYOJ 762 第k个互质数(二分 + 容斥)
生活随笔
收集整理的這篇文章主要介紹了
NYOJ 762 第k个互质数(二分 + 容斥)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
第k個互質(zhì)數(shù)
時間限制:1000?ms ?|? 內(nèi)存限制:65535?KB 難度:4 描述輸入
首先,根據(jù)歐幾里得可知,gcd(b * t + a, b) = gcd(a, b)(t為任意整數(shù)),則如果a與b互質(zhì),則b * t + a與b也一定互質(zhì),如果a與b不互質(zhì),則b*t+a與b也一定不互質(zhì),所以與m互質(zhì)的數(shù)對m取模具有周期性。可以先求出1~m之間有多少個數(shù)與m互質(zhì),然后根據(jù)周期性去求第k個與m互質(zhì)的數(shù)。
#include <cstdio>const int N = 1000005; int a[N];int gcd(int a, int b) {while(b) {int r = a % b;a = b;b = r;}return a; }int main() {int m, k;while(~scanf("%d%d", &m, &k)) {if(m == 1) {printf("%d\n", k);continue;}int num = 0;for(int i = 1; i < m; i++)if(gcd(m, i) == 1)a[num++] = i;int p = k / num;if(k % num == 0) p--;k %= num;if(k == 0) k = num;printf("%d\n", p * m + a[k-1]);}return 0; }用上面的方法可以在POJ上AC,可惜的是,在NYOJ上TLE了。所以要尋找一個更快的解決方案,也就是下面的二分+容斥。
首先對m進行質(zhì)因數(shù)分解,求出m有哪些質(zhì)因數(shù),然后用容斥求[1, mid]內(nèi)與m互質(zhì)的數(shù)有多少個。
判斷的時候,[1,mid]之間與m互質(zhì)的數(shù)的數(shù)量 = mid - (包含一個質(zhì)因子的數(shù)的個數(shù))+ (包含2個質(zhì)因子的書的個數(shù))-(包含3個質(zhì)因子的數(shù)的個數(shù))+ (包含4個質(zhì)因數(shù)的數(shù)的個數(shù))……
#include <cstdio> // 對n進行素因子分解, fac[0]記錄因子個數(shù); int fac[20]; void Div(int n) {int k = 0;for(int i = 2; i * i <= n; ++i){if(n % i == 0) fac[++k] = i;while(n % i == 0) n /= i;}if(n > 1) fac[++k] = n;fac[0] = k; } // 計算[1, n]內(nèi)與m互質(zhì)的數(shù)的個數(shù) int que[1<<10]; int Count(int n, int m) {int g = 0, sum = n;que[++g] = 1;for(int i = 1; i <= fac[0]; ++i){int t = g;for(int j = 1; j <= g; ++j){que[++t] = que[j] * fac[i] * -1;sum += n / que[t];}g = t;}return sum; } // 二分,二分枚舉一個答案mid,計算[1, mid]內(nèi)有多少個數(shù)與m互質(zhì),讓答案與K比較; int Binary_search(int m, int K){int l = 1, r = 2000000000, mid;while(l <= r){mid = (l + r) >> 1;if(Count(mid, m) >= K) r = mid - 1;else l = mid + 1;}return l; } int main() {int m, K;while(scanf("%d%d", &m, &K) != EOF){Div(m);int ans = Binary_search(m, K);printf("%d\n", ans);}return 0; }
總結(jié)
以上是生活随笔為你收集整理的NYOJ 762 第k个互质数(二分 + 容斥)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 你看,公司状告员工不加班,居然还告赢了
- 下一篇: ZOJ 3700 Ever Dream(