• 【ARC122E】Increasing LCMs


    题目

    题目链接:https://atcoder.jp/contests/arc122/tasks/arc122_e
    给定一个长度为 (n) 的正整数序列 (a),要求重排 (a) 中的元素,记 (b_i) 为重排后 ( ext{lcm}(a_1,a_2,cdots,a_i)),要求 (b_1<b_2<cdots<b_n)
    给出一个合法的重排方案。
    (nleq 100;a_ileq 10^{18})

    思路

    考虑最后一位的数字。假设填 (a_i),显然必须满足 ( ext{gcd}(a_i, ext{lcm}_{i eq j}(a_j)) eq a_i)
    那么从后往前不断确定最后一位数字即可。因为如果一个数字可以填在第 (i) 位,那么显然也可以填在第 (j(j<i)) 位。
    时间复杂度 (O(n^3log a))

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    const int N=110;
    int n;
    ll a[N],b[N],g[N][N];
    bool used[N];
    
    ll gcd(ll a,ll b)
    {
    	return b?gcd(b,a%b):a;
    }
    
    ll lcm(ll a,ll b)
    {
    	return a/gcd(a,b)*b;
    }
    
    int main()
    {
    	scanf("%d",&n);
    	for (int i=1;i<=n;i++)
    		scanf("%lld",&a[i]);
    	for (int i=1;i<=n;i++)
    		for (int j=1;j<=n;j++)
    			g[i][j]=gcd(a[i],a[j]);
    	for (int i=n;i>=1;i--)
    	{
    		bool flag=0;
    		for (int j=1;j<=n;j++)
    			if (!used[j])
    			{
    				ll l=1;
    				for (int k=1;k<=n;k++)
    					if (!used[k] && j!=k)
    						l=lcm(l,g[j][k]);
    				if (l<a[j])
    				{
    					b[i]=a[j]; used[j]=1;
    					flag=1; break;
    				}
    			}
    		if (!flag) return printf("No"),0;
    	}
    	printf("Yes
    ");
    	for (int i=1;i<=n;i++)
    		printf("%lld ",b[i]);
    	return 0;
    }
    
  • 相关阅读:
    ARM汇编伪指令介绍.
    初识KITL
    c面试题
    Windows ce的体系结构和功能
    c宏定义的技巧总结
    Build in Windows Mobile
    关于wince注册表
    动态链接库(Dynamic Link Library)学习笔记
    WinCE驱动开发问题精华集锦
    OAL之系统时钟
  • 原文地址:https://www.cnblogs.com/stoorz/p/14879846.html
Copyright © 2020-2023  润新知