Problem Description
It is preferrable to read the pdf statment.
Cuber QQ has signed up for a gambling game, that challenges him to predict the stock price of Quber CC Limited, for the next following n days. He shall make his prediction by filling a table with n intervals, the i-th of which is the predicted interval [li,ri] at the i-th day. If all n prices lie in the corresponding interval, Cuber QQ will win 1 million dollars. Otherwise, he will not earn a single penny.
As is well known, the stock price has a fluctuation limit. For simplicity, we assume the limit up and the limit down are both k, which is an integer. That means, if the stock price at the i-th day is x, the price at the i+1-th day is at most x+k and at least x−k.
Cuber QQ wants to know whether it is possible to manipulate the stock price, without breaking the limitation above of course, so that he can have the 1 million dollars. Since his table has already been submitted, he cannot modify his predicted intervals any more. It has to be done secretly behind the scenes, and smartly cover it up so that no one will notice.
Input
The input starts with an integer T (1≤T≤105), denoting the number of test cases.
For each test case, the first line contains two space-separated integers n and k (2≤n≤105, 0≤k≤109), where n is the number of days and k is the fluctuation limit.
The i-th line of the next n lines contains two space-separated integers li and ri (0≤li≤ri≤109), which is Cuber QQ’s predicted interval in the i-th day. A prediction is believed to be correct if the stock price i-th day lies between li and ri, inclusive.
It is guaranteed that the sum of all n does not exceed 106.
Output
For each test case, first output a single line YES or NO, that states whether Cuber QQ will win the 1 million price.
If YES, in the next line, output a possible price series, a1,a2,…,an, where li≤ai≤ri (1≤i≤n) and |ai−ai+1|≤k (1≤i≤n−1). The integers should be separated with space.
Sample Input
2
3 1
1 6
2 5
3 6
2 3
1 5
10 50
Sample Output
YES
2 3 3
NO
Source
2020 Multi-University Training Contest 8
题意:
有n个区间,要求在每个区间内选一个数,且相邻两个数差值不能大于k。
问是否可行,要求输出方案数。
思路:
第一个数的可选区间就是 [ l 1 , r 1 ] [l1,r1] [l1,r1]
第二个数的可选区间为 [ l 2 , r 2 ] [l2,r2] [l2,r2]与 [ l 1 − k , r 1 + k ] [l1-k,r1+k] [l1−k,r1+k]的区间交集,
后面数的可选区间依次类推。
如果有数的可选区间为空集则说明无解。
对于方案输出的话,我们从最后一个数考虑,从最后一个数的可选区间中任选一个数(不妨选最左边的数),再用这个选的数左右扩展k的距离与前一个数的可选区间作交集,可以保证一定有解。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
typedef long long ll;
using namespace std;
const int maxn = 1e5 + 7;
struct Node {
ll l,r;
}a[maxn],b[maxn];
Node inter(Node v1,Node v2) {
ll r = min(v1.r,v2.r);
ll l = max(v1.l,v2.l);
return Node{
l,r};
}
int main() {
int T;scanf("%d",&T);
while(T--) {
int n,k;scanf("%d%d",&n,&k);
for(int i = 1;i <= n;i++) {
scanf("%lld%lld",&a[i].l,&a[i].r);
}
int flag = 1;
Node now = a[1];
b[1] = now;
for(int i = 2;i <= n;i++) {
now.l -= k;
now.r += k;
Node nex = inter(now,a[i]);
if(nex.l > nex.r) {
printf("NO\n");
flag = 0;break;
}
now = nex;
b[i] = now;
}
if(flag) {
printf("YES\n");
vector<ll>ans;
ans.push_back(now.l);
for(int i = n - 1;i >= 1;i--) {
now.l = now.r = now.l;
now.l -= k;
now.r += k;
Node nex = inter(now,b[i]);
ans.push_back(nex.l);
now = nex;
}
for(int i = ans.size() - 1;i >= 0;i--) {
printf("%lld ",ans[i]);
}
printf("\n");
}
}
return 0;
}