Luogu4571 [JSOI2009]瓶子和燃料(裴蜀定理)題解
阿新 • • 發佈:2020-11-16
前置芝士
裴蜀定理
若\(a\),\(b\)是整數,且\(gcd(a,b)=d\),那麼對於任意的整數\(x\),\(y\),\(ax+by\)都一定是\(d\)的倍數,特別地,一定存在整數\(x\),\(y\),使\(ax+by=d\)成立。
推廣: \(a_1,a_2,a_3...a_n\)為\(n\)個整數,\(d\)是它們的最大公約數,那麼存在整數\(x_1...x_n\)使得\(x_1\times a_1+x_2\times a_2+...x_n\times a_n=d\)。
思路
根據裴蜀定理,外星人所給出的燃料數量為\(k\)個瓶子容積的\(gcd\)。因此問題就轉化為:從\(n\)
我們可以將每個數的因數分解出來(並不只是質因數),記錄每一個因子的出現次數,排序以後選出最大的出現次數\(\geq k\)的就可以了。
另外,本題數值較大,需要開\(map\)。
參考程式碼
#include <cstdio> #include <algorithm> #include <map> using namespace std; const int maxn = 1e6 + 10; int n,cnt,k; struct Num{ int val,num; }p[maxn]; map<int,int> T; bool cmp(Num x, Num y){return x.val > y.val;} int main(){ scanf("%d%d", &n, &k); for(int i = 1; i <= n; ++ i){ int v; scanf("%d", &v); for(int j = 1; j * j <= v; ++ j){ if(v % j == 0){ if(!T[j]) T[j] = ++ cnt, p[cnt].val = j, p[cnt].num ++; else p[T[j]].num ++; int fff = v / j; if(fff == j) continue; if(!T[fff]) T[fff] = ++ cnt, p[cnt].val = fff, p[cnt].num ++; else p[T[fff]].num ++; } } } sort(p + 1, p + 1 + cnt, cmp); for(int i = 1; i <= cnt; ++ i) if(p[i].num >= k) return printf("%d\n", p[i].val), 0; return 0; }