Diff-prime Pairs(思維+素數篩)
題目連結:https://ac.nowcoder.com/acm/contest/7865/J
題目描述
Eddy has solved lots of problem involving calculating the number of coprime pairs within some range. This problem can be solved with inclusion-exclusion method. Eddy has implemented it lots of times. Someday, when he encounters another coprime pairs problem, he comes up with diff-prime pairs problem. diff-prime pairs problem is that given N, you need to find the number of pairs (i, j), where
i
g
c
d
(
i
,
j
)
\frac{i}{gcd(i,j)}
gcd(i,j)i and
j
g
c
d
(
i
,
j
)
\frac{j}{gcd(i,j)}
gcd(i,j)j are both prime and i ,j ≤ N. gcd(i, j) is the greatest common divisor of i and j. Prime is an integer greater than 1 and has only 2 positive divisors.
Eddy tried to solve it with inclusion-exclusion method but failed. Please help Eddy to solve this problem.
Note that pair (i1, j1) and pair (i2, j2) are considered different if i1 ≠ i2 or j1 ≠ j2.
輸入描述
Input has only one line containing a positive integer N.
1 ≤ N ≤ 10
7
^7
7
輸出描述
Output one line containing a non-negative integer indicating the number of diff-prime pairs (i,j) where i, j ≤ N
樣例1
輸入
3
輸出
2
樣例2
輸入
5
輸出
6
思路
方法一:暴力列舉
i
i
i和
j
j
j,會TLE
#include <iostream>
#include <cstdio>
using namespace std;
int n;
int gcd(int a, int b) {
if (b == 0) return a;
return gcd(b, a%b);
}
bool isPrime(int x) {
if (x == 1) return false;//1不是素數
for (int i = 2; i * i <= x; i++) {
if ((x % i) == 0) return false;
}
return true;
}
int main() {
freopen("Diff-prime Pairs.in", "r", stdin);
while (~scanf("%d", &n)) {
int ans = 0;
for (int i = 2; i <= n; i++) {
for (int j = 2; j <= i; j++) {
int g = gcd(i, j);
if (isPrime(i/g) && isPrime(j/g)) {
if (i == j) ans++;//i一定不可能等於j
else ans += 2;
}
}
}
printf("%d\n", ans);
}
return 0;
}
需要注意兩點:
- 函式isPrime()需要單獨判斷1,1不是素數
- 因為pair(i,j)和pair(j,i)是對稱的,所以每次找到一對ans+=2,但程式碼中i==j的情況不可能出現,因為如果i和j相等,gcd(i,j)=i=j,而1不是素數,不會進入if中
方法二:轉換思路,不直接找 i i i和 j j j,而是列舉 i i i和 j j j的最大公因數 g g g,所有滿足 i ∗ g < = n i*g<=n i∗g<=n, j ∗ g < = n j*g<=n j∗g<=n的不相等的 i i i和 j j j就是我們要找的,我們通過素數篩把素數找到,然後用陣列sum[ ]記錄字首素數的個數
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
const int N = 1e7+7;
int n;
int a[N], sum[N];
void init(int n) {
memset(sum, 0, sizeof(0));
a[0] = a[1] = 1;
for (int i = 2; i <= n; i++) {
if (a[i] == 0) {
sum[i] = 1;
for (int j = 2*i; j <= n; j+=i) {
a[j] = 1;
}
}
}
for (int i = 1; i <= n; i++) {
sum[i] += sum[i-1];
}
}
int main() {
freopen("Diff-prime Pairs.in", "r", stdin);
while (~scanf("%d", &n)) {
init(n);
ll ans = 0;
for (int g = 1; g <= n; g++) {
ans += sum[n/g] * (sum[n/g]-1);
}
printf("%lld\n", ans);
}
return 0;
}
相關文章
- 素數篩
- 【數論】素數篩法
- 素數篩 : Eratosthenes 篩法, 線性篩法
- 素數個數 <埃式篩 && 尤拉篩>
- 素數篩(埃氏篩法與尤拉篩)
- [演算法]: 素數篩法演算法
- Prime Path(POJ - 3126)【BFS+篩素數】
- wenbao與篩法素數及判斷模板
- 第六章 數學問題 ----------6.13 素數的篩法(第十萬零二個素數)
- 洛谷P3383 【模板】線性篩素數
- 面試官本拿求素數搞我,但被我優雅的“回擊“了(素數篩)面試
- 面試官本拿求素數搞我,但被我用素數篩優雅的“回擊“了面試
- 增補部落格 第二十篇 python 篩法求素數Python
- 尤拉素數篩選與命令列傳參啟動C程式命令列C程式
- 組合計數思維題
- 思維體系---技術思維、業務資料思維、產品思維、複合思維
- 551. Preparing Problem(思維+數學)
- 淺析工具思維、產品思維、品牌思維與定位
- PAT-B 1013 數素數 【素數】
- 求職思維和招聘思維求職
- 質數篩
- 尤拉篩線性篩質數
- 素數
- B族維生素
- 把流量思維變成留量思維
- 框架思維框架
- 極思維
- 黑客思維黑客
- PAT-B 1007 素數對猜想【素數】
- 數論(1):素數
- CF 1971 F. Circle Perimeter (*1600) 思維 數學
- POJ 1113 Wall(思維 計算幾何 數學)
- 線性篩合數
- 你是整體思維還是分析思維? - kentbeck
- 計算思維
- 模型思維(01)模型
- 【測評】思維導圖的戰爭!手繪和數字思維導圖哪個更實用?
- 提升思維邏輯—SimpleMind Pro(思維導圖) for Mac/winMac