題意:給你一串數字,問選擇4個數且這四個數的最大公因數為1的選法為多少種
解法:很容易想到容斥原理,答案為選擇四個數的所有種數-四個數存在最大公因數為質數+四個數存在最大公因數為兩個質數之積-四個數存在最大公因數為三個質數之積。。。
就是處理各個由質因子相乘得到的因子的數量比較麻煩。
首先,題目給的資料範圍是10000,而2*3*5*7*11*13>10000 所以每個數的質因子最多只有五個
那麼對於每個數,我們只要求出它的幾個質因子組合而成的數目就好,這裡有個優化,假設這個數有a個質因子,那麼由其中i個質因子相乘得到的數和由其中a-i個質因子相乘得到的數一一對應,二者乘積為這個數所有質因子的乘積,所以4個和5個的組合是不用重新求的,只要用所有數的乘積除一下就好,那麼最多迴圈三次取三個不同的質因子,時間複雜度減為5*5*5*10000,同時記錄這個數是由幾個數相乘得到。
最後求出了每個由出現的質數組成的因子的數量,這個因子的大小不會超過10000,根據因子的質因子數確定係數的正負然後直接用容斥原理就可以了。
#define _crt_secure_no_warnings
#include#include#include#include#include#includeusing namespace std;
#define ll __int64
int n,cnt[10005],num[10005];
int mul_cnt[10005];
ll c[10005][10],ans;
bool isprime[10005],mark[10005];//每個因子該加還是減
vectorv[10005];//每個數的因子
void init()
void input()
n=unique(num,num+n)-num;
}void pre()
} return;
}void cnt_m()
for(int j=0;j1)
}if(a==4)
mul_cnt[sum]+=cnt[num[i]];
mark[sum]=1;
} for(int i=2;i<=10000;i++) }
int main()
return 0;
}
poj3904 容斥原理)
可以得到這樣的關係 奇數加 偶數減 題目大意 給一串數字,求解互質四元組的個數 注意不必兩兩互質 解題思路 網上有很多 但是詳細講解的很少,這裡結合筆者的思路詳細論述一下解題思路,耐心一看。首先容易想到,想計算不互質的四元組的個數,再用總的減去,關鍵是怎樣計數不互質四元組的個數?列舉公約數,對於同乙...
POJ 3904 Sky Code 容斥原理
題意 選出最大公約數為1的四元組的方案 思路 容斥原理 總的方案c n,4 減去t 1 t 2 t 3 kt k t i 表示四元組質因子的個數為i的方案數 include include include using namespace std const int maxn 10010 typede...
POJ3904 Sky Code 容斥原理
這道題很容易想到用總的情況減去不互素的情況,需要統計不同素因子對應的資料個數,但這樣會多算 比如2的因子減過一次,3的因子減過一次,這時6的情況 eg 6,12,18,24 就多減了一次 因此想到用容斥原理。問題的關鍵在於,怎麼得到不同素因子組合對應的情況。附上大佬部落格orz 這篇部落格講的很清楚...