对照着 sbno333 大佬的这篇tj写的:https://www.luogu.com.cn/article/eha0hzkc。
评测结果如题所示,评测记录在此:Link。
感觉自己改着改着都要和tj一样了,故玄关。玄关量按帮助多少给予1-2关。
最后贴代码。
#include<bits/stdc++.h>
#define int long long
using namespace std;
int check(int s,int n,int d,int k){
int u = s * k,v,w;
if (u > n)return 2;
u = n - u;
v = s * s + s;
v *= k;
v /= 2;
if (v > d)return 2;
v = d - v;
w = u * s;
if (w < v)return 0;
w -= v;
if (u > v)return 2;
return 1;
}
void print(int s,int n,int d,int k){
int u,v,w,f;
u=s*k;
u=n-u;
v=s * s + s;
v/=2;
v*=k;
v=d-v;
w=u*s;
w-=v;
f = 0;
for (int i=0;i<s;i++){
for (int j=0;j<k;j++){
cout << i*k+1;
cout << ' ';
f++;
}
}
int f1,f2;
f1=w/(s-1);
f2=w%(s-1);
f2=s-f2;
f1=u-f1;
if (f2 != 0){
f1--;
}
while (f1--){
cout<<(s-1)*k+1<<" ";
f++;
}
while (f2 != s){
cout<<(f2-1)*k+1<<" ";
f++;
}
for (int i=f+1;i<=n;i++){
cout << "1 ";
}
cout <<'\n';
return;
}
void find(int n,int d,int k){
if (k > n){
cout << "NO\n";
return;
}
if (n == 0){
cout << "NO\n";
return;
}
if (n == d){
cout << "YES\n";
for (int i=1;i<=n;i++){
cout << "1 ";
}
cout << '\n';
}
int l=2,r=1e10+10;
while (l<r){
int mid = (l+r) / 2;
int all = check(mid,n,d,k);
if (all == 1 || all == 2){
r = mid - all + 1;
}
else{
l = mid + 1;
}
}
if (check(r,n,d,k) == 1){
cout << "YES\n";
print(r,n,d,k);
}
else{
cout << "NO\n";
}
return;
}
short put(){
int n,d,k;
cin >> n >> d >> k;
find(n,d,k);
return 0;
}
signed main(){
int T;
cin >> T;
while (T--){
put();
}
}