标签:clu ble -- isp using blog include display 整数
题目:https://vjudge.net/contest/389321#problem/D
题意:
给出N个正整数,找出N个数两两之间最大公约数的最大值。例如:N = 4,4个数为:9 15 25 16,两两之间最大公约数的最大值是15同25的最大公约数5。
第1行:一个数N,表示输入正整数的数量。(2 <= N <= 50000) 第2 - N + 1行:每行1个数,对应输入的正整数.(1 <= S[i] <= 1000000)
参考题解:https://blog.csdn.net/qq_28954601/article/details/52104446
题解:用桶来存每一个数,并且记录最大值为big。然后从假设最大因子i从big到1,对于每次假设,寻找ni的个数,如果大于等于2说明最大因子必为i。
我刚开始看到参考题解的时候,第一反应:这居然不会超时咩?
后来算了一下,对于每个i,它一共执行big/i次。
那么对于最大的情况,big为1000000,那么i从1000000到1,一共执行(1000000/1+1000000/2+...+1000000/1000000)次。用程序算了一下,这个和是13970034,在1s的执行范围内,所以不会超时。
筛法好神奇。
1 #include <iostream> 2 #include <stdio.h> 3 #include <algorithm> 4 #include <queue> 5 #include <stack> 6 #include <cstring> 7 #include <map> 8 #include <set> 9 #include <cmath> 10 #define ALL(x) x.begin(),x.end() 11 using namespace std; 12 typedef long long ll; 13 const ll mx=5e4+100; 14 const ll mx2=1e6+10; 15 ll n, v[mx]; 16 ll num[mx2]; 17 18 void solve(){ 19 scanf("%lld", &n); 20 ll big=0; 21 for(ll i=1;i<=n;i++){ 22 scanf("%lld", &v[i]); 23 num[v[i]]++; 24 big=v[i]>big?v[i]:big; 25 } 26 for(ll i=big;i>=1;i--){ 27 ll gs=0; 28 for(ll j=i;j<=big;j+=i){ 29 gs+=num[j]; 30 if(gs>=2){ 31 printf("%lld\n", i); 32 return ; 33 } 34 } 35 } 36 37 } 38 int main(){ 39 solve(); 40 return 0; 41 }
标签:clu ble -- isp using blog include display 整数
原文地址:https://www.cnblogs.com/ReflexFox/p/14723297.html