首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

POJ 2773:二分 + 容斥原理求第 K 個互質數

     編輯:關於C++

問題描述

給定 m (≤1e6) 和 K (≤1e8),求第 K 個與 m 互質的正整數。

核心思路:二分答案 + 容斥計數

設 f(x) = [1,x] 中與 m 互質的數個數。f(x) 單調遞增。二分最小 x 使 f(x) ≥ K,即為答案。
f(x) = x - Σ_{p|m} x/p + Σ_{p(容斥原理)。
m 的質因子數 ≤ 7(因 2*3*5*7*11*13*17>1e6),子集枚舉 2^7=128 極快。

代碼實現

vector primes; // m 的質因子
LL calc(LL x) {
    LL res=0;
    for (int mask=1; mask<(1<>i&1) prod*=primes[i];
        if (bits&1) res += x/prod;
        else res -= x/prod;
    }
    return x - res; // 互質數個數
}

int main() {
    LL m, K;
    while (cin>>m>>K) {
        primes.clear();
        LL tm=m;
        for (LL i=2;i*i<=tm;i++) if (tm%i==0) {
            primes.push_back(i);
            while (tm%i==0) tm/=i;
        }
        if (tm>1) primes.push_back(tm);
        LL l=1, r=1LL<<60, ans=-1;
        while (l<=r) {
            LL mid=(l+r)>>1;
            if (calc(mid)>=K) { ans=mid; r=mid-1; }
            else l=mid+1;
        }
        printf("%lld\n", ans);
    }
    return 0;
}

關鍵點

  • 質因子分解 O(√m)。
  • 容斥枚舉所有非空子集,位運算加速。
  • 二分上界 1LL<<60 足夠大(K≤1e8, m≥1 時答案 < 2e8)。
  • __builtin_popcount 計算集合大小決定符號。

總結

POJ 2773 是「二分答案 + 容斥計數」的經典組合。關鍵在於將「第 K 個滿足性質的數」轉化為「計數函數單調性」,並利用質因子數少的特性高效實現容斥。模板極其通用,適用於各類「第 K 個互質/不被整除」問題。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved