【JZOJ 4699】 Password

    xiaoxiao2025-09-05  632

    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; }
    转载请注明原文地址: https://ju.6miu.com/read-1302352.html
    最新回复(0)