• CodeForces 1305E. Kuroni and the Score Distribution(构造)


    传送门

    题意

    要求构造一个数列 (a_1,a_2,...,a_n),满足 (1le a_ile 10^9),存在且仅存在 (m) 对三元组 ((i,j,k)) 满足 (a_i+a_j=a_k,1le i<j<kle n)

    题解

    看了官方题解写的,这里就翻译一下官方题解
    显然数列 (1,2,...,n) 中存在三元组的数量最多。对于 (a_k=k),它前面的数列 (1,2,...,k-1) 两两之和等于 (k),那么对于 (a_k),存在 (lfloorfrac{k-1}{2} floor) 对三元组。
    显然最多可以有 (sum_{k=1}^{n}lfloorfrac{k-1}{2} floor) 对三元组,如果 (m) 大于这个值,显然构造不出来。
    如果可以构造,那么找到位置 (k) 满足 (sum_{i=1}^{k}lfloorfrac{i-1}{2} floor le m)(sum_{i=1}^{k+1}lfloorfrac{i-1}{2} floor > m)
    (k) 位保持 (a_i=i),第 (k+1) 位就只应该与前缀 (1,2,...,k) 构成 (m-sum_{i=1}^{k}lfloorfrac{i-1}{2} floor) 个三元组。
    根据之前构造三元组的规律,可以发现在 (1,2,...,k) 中,长度为 (l*2) 的后缀再添上一个项 (k-2*l+1+k) 可以构成 (l) 个三元组,
    那么因为我要 (m-sum_{i=1}^{k}lfloorfrac{i-1}{2} floor) 个三元组,就要添上一个 (k-2*(m-sum_{i=1}^{k}lfloorfrac{i-1}{2} floor)+1+k)
    到这里,我们用了 (k+1) 项将 (m) 个三元组都凑齐了,剩余的项一个三元组都不能产生。
    因为按照这个构造规律,前 (k+1) 项不可能大于 (5000),那么其他项只需要从 (10^8) 开始依次递增 (10^4) 就行了。

    代码

    #include <iostream>
    #include <vector>
    using namespace std;
    int n,m,a[5050];
    
    int main(){
    	cin>>n>>m;
    	int pos=0,sum=0;
    	while(pos<n&&sum+pos/2<=m) sum+=pos/2,pos++;
    	if(pos==n&&sum<m) return printf("-1
    "),0;
    	for(int i=1;i<=pos;i++) printf("%d ",i);
    	if(pos==n) return 0;
    	printf("%d ",2*pos+1-2*(m-sum));
    	for(int i=pos+2;i<=n;i++) printf("%d ",(int)(1e8+1e4*(i-pos-2)));
    	return 0;
    }
    
  • 相关阅读:
    Ubuntu 中软件的安装、卸载以及查看的方法总结
    无锁队列的环形数组实现
    Geodatabase模型
    地图投影与ArcGIS坐标系转换
    ARCGIS动态画点
    ArcEngine数据删除几种方法和性能比较
    AE开发技术文档--8种数据访问方法
    Hibernate 的HQL和sql有什么区别
    ActionContextCleanUp作用
    Hibernate延迟加载与opensessioninviewFilter
  • 原文地址:https://www.cnblogs.com/BakaCirno/p/12409554.html
Copyright © 2020-2023  润新知