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;
}
相關文章
- Find Terrorists(素數篩選+素因子分解)Error
- [演算法]: 素數篩法演算法
- 數論線性篩總結 (素數篩,尤拉函式篩,莫比烏斯函式篩,前n個數的約數個數篩)函式
- 面試官本拿求素數搞我,但被我優雅的“回擊“了(素數篩)面試
- 面試官本拿求素數搞我,但被我用素數篩優雅的“回擊“了面試
- POJ 2262 Goldbach's Conjecture (求解素數的一般篩和線性篩)Go
- 尤拉素數篩選與命令列傳參啟動C程式命令列C程式
- ACdream 1112 Alice and Bob (博弈&&素數篩選優化)優化
- 組合計數思維題
- 思維體系---技術思維、業務資料思維、產品思維、複合思維
- 東京大學思維素養訪談集1:如何思考
- 淺析工具思維、產品思維、品牌思維與定位
- 素數之年,IT運維其實可以很簡單運維
- HDU 4542 小明系列故事——未知剩餘系 (DFS 反素數 篩子預處理)
- 黑客思維黑客
- 思維模式模式
- ACM 素數ACM
- 組合思維與繼承思維的不同繼承
- 【測評】思維導圖的戰爭!手繪和數字思維導圖哪個更實用?
- 模型思維(01)模型
- 素數計數函式函式
- 《計算思維史話》思維導圖——持續更新
- 創新思維框架:第一原則思維 - Neil Kakkar框架
- 你是整體思維還是分析思維? - kentbeck
- 提升思維邏輯—SimpleMind Pro(思維導圖) for Mac/winMac
- 什麼是產品思維和專案思維? - Shreyas
- 企業數字化轉型:聊聊資料思維!
- 高等數學-多元函式微分學思維導圖函式
- 物件導向正規化需要數學思維嗎?物件
- 約束定理+質數篩
- Palindrome PairsAI
- Swap Nodes in PairsAI
- 英語思維與物件導向分析思維的關係物件
- 思維之道 --讀《質量.軟體.管理 系統思維》(2)
- 思維之道 --讀《質量.軟體.管理 系統思維》(1)
- 思維之道 --讀《質量.軟體.管理 系統思維》(3)
- 前端思維導圖前端
- Java思維理清思路Java