• IOI2021集训队作业 173QE Equal Numbers


    给你(n)个数,每次可以将一个数乘任意正整数。对于(kin[0,n]),求进行(k)次操作得到的数列中不同的数的最小值。

    (nle 3*10^5)


    统计每个数的出现次数。将数分成两类:(A)类,存在另一个数为它的不为(1)的正整数倍;(B)类,不存在另一个数为它的不为(1)的正整数倍。

    一种情况是(B)类数不动,于是每种(A)类数的代价是个数次操作,贡献是(-1)

    另一种情况是(B)类数动了。为了使(B)类数产生贡献,必须要钦定另一个数变成所有数的(LCM)。为了最优取出现次数最小的((A)类或(B)类都行)。


    using namespace std;
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define N 300005
    #define M 1000000
    int n;
    int buc[M+5];
    int a[N],b[N];
    int na,nb;
    int f[N];
    int main(){
    //	freopen("in.txt","r",stdin);
    	scanf("%d",&n);
    	for (int i=1;i<=n;++i){
    		int x;
    		scanf("%d",&x);
    		buc[x]++;
    	}
    	int cnt=0;
    	for (int i=M;i>=1;--i)
    		if (buc[i]){
    			cnt++;
    			bool bz=0;
    			for (int j=i+i;j<=M && !bz;j+=i)
    				if (buc[j])
    					bz=1;
    			if (bz==0)
    				b[++nb]=buc[i];
    			else
    				a[++na]=buc[i];
    		}
    	sort(a+1,a+na+1);
    	int s=0;
    	f[s]=0;
    	for (int i=1;i<=na;++i){
    		s+=a[i];
    		f[s]=max(f[s],i);
    	}
    	if (na+nb>=2){
    		for (int i=1;i<=nb;++i)
    			a[++na]=b[i];
    		sort(a+1,a+na+1);
    		s=a[1]+a[2];
    		f[s]=max(f[s],1);
    		for (int i=3;i<=na;++i){
    			s+=a[i];
    			f[s]=max(f[s],i-1);
    		}
    		for (int i=1;i<=n;++i)
    			f[i]=max(f[i-1],f[i]);
    	}
    	for (int i=0;i<=n;++i)
    		printf("%d ",cnt-f[i]);	
    	return 0;
    }
    
  • 相关阅读:
    ES6-10笔记(class类)
    ES6-10笔记(let&const -- Array)
    小程序的表单提交
    小程序表单回显
    小程序template模板的使用和模板多数据传递
    微信小程序的初始配置
    babel 版本原因运行报错,解决办法
    webpack 和 webpack-cli 安装和使用中出现的问题
    jQuery中操作属性的方法attr与prop的区别
    javaScript 添加和移除class类名的几种方法
  • 原文地址:https://www.cnblogs.com/jz-597/p/13824325.html
Copyright © 2020-2023  润新知