题目大意
对于两个序列 (x_i, y_i), 使得他们满足下列条件:
- (x_i, y_i ge 0, x_i + y_i = m)
- (sumlimits^{n}_{i=1}x_i = k)
- 有且仅有 (p) 个互不相同的 (j) 使 (x_j = maxlimits^n_{i-1} {x_i})
Solution:
直接贪心即可。首先直接 (k / p) 作为前 (p) 个的最大值,可以证明这样一定不会更劣。当然,这里也可以利用二分来判断答案是否合法,从而得到一个合法解,但没有必要。
接着,考虑如何输出剩下的解。首先,我们要保证剩下的所有 (x) 一定要小于 (k / p),所以考虑部分答案设为 (k / p - 1), 那么不断将 (k) 减去该值,如果小于,则输出不整的那一剩下部分,最后全部输出 (0) 即可。
代码:
#include <bits/stdc++.h>
using namespace std;
#define N 1000010
#define int long long
template <class T>
inline void read(T& a){
T x = 0, s = 1;
char c = getchar();
while(!isdigit(c)){
if(c == '-') s = -1;
c = getchar();
}
while(isdigit(c)){
x = x * 10 + (c ^ '0');
c = getchar();
}
a = x * s;
return ;
}
int n, m, k, p;
signed main(){
read(n), read(m), read(k), read(p);
int pin = k / p;
if(pin > m) pin = m; // 平均值
if((n - p) * (pin - 1) < (k - pin * p) || (k == 0 && p != n)){
printf("no");
return 0;
}
if(n == p && (double)n / p != n / p){
printf("no
");
return 0;
}
printf("yes
");
for(int i = 1; i <= p; i++)
printf("%lld %lld
", pin, m - pin);
int cnt = 0;
k -= p * pin;
while(k >= pin && cnt < n - p){
printf("%lld %lld
", pin - 1, m - pin + 1);
k -= pin - 1;
cnt++;
}
if(k != 0){
printf("%lld %lld
", k, m - k);
cnt++;
}
for(int i = 1; i <= n - p - cnt; i++)
printf("0 %lld
", m);
return 0;
}