题目大意
对于两个序列 \(x_i, y_i\), 使得他们满足下列条件:
- \(x_i, y_i \ge 0, x_i + y_i = m\)
- \(\sum\limits^{n}_{i=1}x_i = k\)
- 有且仅有 \(p\) 个互不相同的 \(j\) 使 \(x_j = \max\limits^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\n");
return 0;
}
printf("yes\n");
for(int i = 1; i <= p; i++)
printf("%lld %lld\n", pin, m - pin);
int cnt = 0;
k -= p * pin;
while(k >= pin && cnt < n - p){
printf("%lld %lld\n", pin - 1, m - pin + 1);
k -= pin - 1;
cnt++;
}
if(k != 0){
printf("%lld %lld\n", k, m - k);
cnt++;
}
for(int i = 1; i <= n - p - cnt; i++)
printf("0 %lld\n", m);
return 0;
}