看了大佬的代码,感觉有一点看不懂,对孰弱(我)不太友好,所以写了一版更容易理解的(可能把)

对于n因为左右都不会有比它更大的了,所以是2*n,对于n-1,n只会在它的左右一边,所以L(),R ()中只会有一次n-1;

无论怎么样都会有3*n-1

所以L+R最小的就是n-1和n位于两端 min=3*n-1;

最大的情况就是按照递增 max=(1+n)*n/2;

首先进行特判对于n==1 || n==2 || k不位于min和max之间进行输出

然后就是对一般情况进行构造,很简单就可以想到,位于n-1和n之间的数都不会被L和R算进去

所以就可以进行贪心,比如从左往右贪心,使和到达k

然后把剩下的数都放到n-1与n之间,最后输出就好拉

#include <bits/stdc++.h>
using namespace std;
const long long MOD=998244353;
const int N=2e5+10;
int main() {
ios::sync_with_stdio(false);cin.tie(0);


int n;
long long k;
cin>>n>>k;
if(n==1){
	if(k==2) cout<<1<<endl;
	else cout<<-1<<endl;
	return 0;
}
if (n == 2) {
    if(k==5) cout<<1<<' '<<2<<endl;
    else cout<<-1<<endl;
    return 0;
}
long long sum=n*(n+1)/2;
if(1LL*n*(n+1)/2+n<k || k<3LL*n-1){
	cout<<-1;
	return 0;
}
long long rest=k-3*n+1;
vector<bool>mark(n+1,1);
vector<int>vec;
	for(int i=n-2;i>=1;i--){
		if(i<=rest){
			mark[i]=0;
			rest-=i;
			vec.push_back(i);
		}
		if(rest==0) break;
	}
//因为是从左往右贪心,所以对于找出来的数要进行逆序输出
for(int i=vec.size()-1;i>=0;i--){
	cout<<vec[i]<<' ';
}
cout<<n-1<<' ';
for(int i=1;i<=n-2;i++){
	if(mark[i]){
		cout<<i<<' ';
	}
}
cout<<n<<endl;
return 0;

}