码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces #322 (Div. 2) C GCD Table

时间:2015-10-04 06:42:19      阅读:171      评论:0      收藏:0      [点我收藏+]

标签:

题意简述:

给定一个长度为$n$的序列 将这个序列里的数两两求$gcd$得到$n^2$个数

将这$n^2$个数打乱顺序给出 求原序列的一种可能的情况

-----------------------------------------------------------------------------------------------------------------------

比赛时一直去想有什么特殊的性质(找规律) 比如这些数里为一个数的倍数的数一定是平方个

然而按照这样的思路去想又会有什么分解因式等等 最后直接在这一部分就T掉

-----------------------------------------------------------------------------------------------------------------------

比赛结束后$ dwj$ 给了我一份他的$AC$代码 发现原来是增量法的运用

我们先假设原序列是非严格递减的

我们把这些数排序后 设已经求得原序列前$k$项 并且把前$k$项相互之间的$gcd$得到的数全部删掉了

剩下来的最大的那个肯定是原序列中的$k+1$项

然后通过这个数和前$k$项的数$gcd$得到的数我们把它们全部删掉

剩下来的最大的那个肯定是原序列中的$k+2$

…………

对于删数的操作 我们可以用优先队列来维护 然后这题就解决了

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int N=510;
int a[N*N],ans[N];
int n,len;
priority_queue <int> q;
int main()
{
    scanf("%d",&n);
    int n2=n*n;
    for(int i=1;i<=n2;++i)
        scanf("%d",&a[i]);
    sort(a+1,a+1+n2);
    int i=n2;
    while(i)
    {
        if(q.empty()||q.top()!=a[i])
        {
            for(int j=1;j<=len;++j)
            {
                q.push(__gcd(ans[j],a[i]));
                q.push(__gcd(ans[j],a[i]));
            }
            printf("%d ",ans[++len]=a[i]);
        }
        else
            q.pop();
        --i;
    }
    return 0;
}

 

Codeforces #322 (Div. 2) C GCD Table

标签:

原文地址:http://www.cnblogs.com/sagitta/p/4854111.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!