题意:
给两个整数n,m
让输出一个长度为n的数组,满足
的组数为m组
思路:
考虑如何让符合的三元组数更多,即1,2,3,4,5,6…这样的时候,
那每个位置能贡献几组满足题意的三元组呢
计算发现他们的贡献为
0,0,1,2,4,6,9,12…即
意思就是我每增加一个数,它都能贡献
做法:
记录当前已经有多少组了,每次
然后考虑边界,在增加一个数时,发现
了,意思就是这个位置不能是
了,那应该是多少呢?我们考虑还需要几组,显然还需要
组,那添加哪个数刚好增加p组呢
往前找
个数,比如
,当前要在
的位置添加数
40,41,42,43,44,
45,46,47,48,49,我们发现这
个数,可以构成p对和都是
那
,是不是就可以增加
组
所以
应该等于
这样
组已经完成了,如何数组
还没有填满,后面的就随便填,保证不会再组成
即可,因为
总共才
,选一个大点的数开始,每次直接增加
,肯定不可能再组成
特判: 如果
,说明数组填满之后还不够,输出
代码:
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <math.h>
#include <map>
#include <queue>
#include <set>
#include <stack>
typedef long long ll;
#define PII make_pair
#define pb push_back
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int MAXN=2e5+50;
const int inf=0x3f3f3f3f;
const int M=5000*4;
int a[5050];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
int cnt=0;
int flag=0;
int k=0;
for(int i=1;i<=n;i++){
if(flag==1){//已经够m个了
a[i]=5e8+k;
k+=5050;
continue;
}
if(cnt+(i-1)/2<=m){
a[i]=i;
cnt+=(i-1)/2;
}
else {
int p=m-cnt;
cnt+=p;
a[i]=i-1+i-2*p;
flag=1;//刚好m个
}
}
if(cnt!=m)printf("-1\n");
else {
for(int i=1;i<=n;i++)
printf("%d%c",a[i],i==n?'\n':' ');
}
return 0;
}