容斥原理
定義
在計數時,必須注意沒有重複,沒有遺漏
爲了使重疊部分不被重複計算,人們研究出一種新的計數方法
這種方法的基本思想是:先不考慮重疊的情況,把包含於某內容中的所有對象的數目先計算出來,然後再把計數時重複計算的數目排斥出去,使得計算的結果既無遺漏又無重複
這種計數的方法稱爲容斥原理
想必大家都不想讀這麼多字,而且讀了還不一定懂
所以我們用維恩圖來看一下:
簡單明瞭,其實容斥原理就是小學學的重疊問題
公式
在百度百科中所展現的式子是這樣的
而對於像我這樣的初學者來看無疑是“天書”
所以我總結了一個式子
公式含義
如圖,當我們減去兩兩相交的部分時,三個部分都重合的那個被減去了三次
因此需要加上一次
其實容斥也就這麼多了
作爲Oier,當然我們還要會敲代碼
找了一道模板題
HDU Eddy's愛好
代碼:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int prime[18]= {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59};
LL res, n;
int a[5];
void dfs(int cur, int num, int cnt, LL sum) { // 從素數表cur位置開始,當前一共num個,需要cnt個,當前素數乘積爲sum
if (num == cnt) {
LL temp = (LL) pow(n + 0.5, 1.0 / sum);
if (temp > 1) res += temp - 1; // 減去1的情況
return;
}
for (int i = cur; i < 17; i++) {
if (sum * prime[i] < 60) dfs(i + 1, num + 1, cnt, sum * prime[i]);//如果素數沒到60,則這個素數可以取
else dfs(i + 1, num, cnt, sum);// 否則跳過該數
}
}
int main() {
while (scanf("%d", &n) != EOF) {
LL sum = 0;
for (int i = 1; i <= 3; i++) {
res = 0;
dfs(0, 0, i, 1);
if (i & 1) sum += res;
else sum -= res;
}
printf("%d\n", sum + 1);
}
return 0;
}