Description
Analysis
这题比赛时的思路是对的,但是少考虑了一些情况,估了100得了0
其实可以统计一下A数组的每个数出现了多少次,按数的大小排好序。
你可以计算出当前这个数的出现次数,用n^2的时间再计算当前数对后面的数的影响。
至于计算当前的数,解个方程就好了。
具体细节看代码。
Code
#include<cstdio>
#include<cmath>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef long long ll;
const int N=1010,M=100010;
int n,m,g0;
ll a[N*N],b[N],ans[N],bz[M];
struct lyd
{
ll x,y,z;
}c[M];
bool cmp(int a,int b){return a>b;}
int gcd(int x,int y)
{
if(x%y==0) return y;
else return gcd(y,x%y);
}
int find(int x)
{
int l=1,r=m,mid;
while(l<r)
{
mid=(l+r)>>1;
if(x<c[mid].x) l=mid+1;
else r=mid;
}
return l;
}
int main()
{
scanf("%d",&n);
fo(i,1,n*n) scanf("%lld",&a[i]);
sort(a+1,a+n*n+1,cmp);
fo(i,1,n*n)
if(a[i]!=a[i-1]) c[++m].x=a[i],c[m].y=1;
else c[m].y++;
fo(i,1,m)
{
ll B=2*bz[i],C=-c[i].y;
ll times=(-B+sqrt(B*B-4*C))/2;
if(times<=0) continue;
c[i].z=times;
fo(j,1,i-1)
{
if(c[j].z<=0) continue;
int t=gcd(c[i].x,c[j].x);
int pos=find(t);
bz[pos]+=c[i].z*c[j].z;
}
fo(j,i+1,m)
if(c[i].x%c[j].x==0) bz[j]+=c[i].z;
fo(j,1,times) ans[++ans[0]]=c[i].x;
}
sort(ans+1,ans+ans[0]+1,cmp);
fo(i,1,ans[0]) printf("%lld ",ans[i]);
return 0;
}