C题太神窝看不懂……

核聚变反应强度

  QwQ很容易发现次小的公约数一定是gcd的一个约数,然后……我就傻逼地去每次算出a[1],a[i]的gcd,然后枚举约数……这复杂度……哦呵呵。。。

  正解是先找到a[1]的所有质因数啊……然后在刚刚那个算法的“枚举gcd的约数”的时候直接枚举这些质因数就好了……

 1 //UOJ Round3 A
 2 #include<vector>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<cstdlib>
 6 #include<iostream>
 7 #include<algorithm>
 8 #define rep(i,n) for(int i=0;i<n;++i)
 9 #define F(i,j,n) for(int i=j;i<=n;++i)
10 #define D(i,j,n) for(int i=j;i>=n;--i)
11 using namespace std;
12 typedef long long LL;
13 inline LL getint(){
14     LL r=1,v=0; char ch=getchar();
15     for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-1;
16     for(; isdigit(ch);ch=getchar()) v=(v<<3)+(v<<1)-'0'+ch;
17     return r*v;
18 }
19 const int N=1e6+10;
20 /*******************template********************/
21 
22 int n,tot,cnt;
23 LL a[N],b[N],prime[N];
24 bool vis[N];
25 inline LL gcd(LL a,LL b){return b?gcd(b,a%b):a;}
26 int main(){
27 #ifndef ONLINE_JUDGE
28     freopen("A.in","r",stdin);
29     freopen("A.out","w",stdout);
30 #endif 
31     n=getint();
32     F(i,1,n) a[i]=getint();
33     for(LL i=2;i*i<=a[1];i++)
34         if (!vis[i]){
35             prime[++tot]=i;
36             for(LL j=i+i;j*j<=a[1];j+=i) vis[j]=1;
37         }
38     F(i,1,tot) if (a[1]%prime[i]==0) b[++cnt]=prime[i];
39     LL tmp;
40     F(i,1,n){
41         tmp=gcd(a[1],a[i]);
42         if (tmp==1) {printf("-1 "); continue;}
43         bool sign=1;
44         F(j,1,cnt)
45             if (tmp%b[j]==0){
46                 printf("%lld ",tmp/b[j]);
47                 sign=0;
48                 break;
49             }
50         if (sign) printf("1 ");
51     }
52     return 0;
53 }
View Code

相关文章: