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

传送门

题意

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

题解

看了官方题解写的,这里就翻译一下官方题解
显然数列 \(1,2,...,n\) 中存在三元组的数量最多。对于 \(a_k=k\),它前面的数列 \(1,2,...,k-1\) 两两之和等于 \(k\),那么对于 \(a_k\),存在 \(\lfloor\frac{k-1}{2}\rfloor\) 对三元组。
显然最多可以有 \(\sum_{k=1}^{n}\lfloor\frac{k-1}{2}\rfloor\) 对三元组,如果 \(m\) 大于这个值,显然构造不出来。
如果可以构造,那么找到位置 \(k\) 满足 \(\sum_{i=1}^{k}\lfloor\frac{i-1}{2}\rfloor \le m\)\(\sum_{i=1}^{k+1}\lfloor\frac{i-1}{2}\rfloor > m\)
\(k\) 位保持 \(a_i=i\),第 \(k+1\) 位就只应该与前缀 \(1,2,...,k\) 构成 \(m-\sum_{i=1}^{k}\lfloor\frac{i-1}{2}\rfloor\) 个三元组。
根据之前构造三元组的规律,可以发现在 \(1,2,...,k\) 中,长度为 \(l*2\) 的后缀再添上一个项 \(k-2*l+1+k\) 可以构成 \(l\) 个三元组,
那么因为我要 \(m-\sum_{i=1}^{k}\lfloor\frac{i-1}{2}\rfloor\) 个三元组,就要添上一个 \(k-2*(m-\sum_{i=1}^{k}\lfloor\frac{i-1}{2}\rfloor)+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\n"),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;
}
posted @ 2020-03-04 14:56  BakaCirno  阅读(345)  评论(0编辑  收藏  举报