Fluctuation Limit
Time Limit: 2000/2000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
Special Judge
Problem Description
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 n n days. He shall make his prediction by filling a table with n n n intervals, the i i i-th of which is the predicted interval [ l i , r i ] [l_i,r_i] [li,ri] at the i i i-th day. If all n n 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 k k, which is an integer. That means, if the stock price at the i i i-th day is x x x, the price at the i + 1 i+1 i+1-th day is at most x + k x+k x+k and at least x − k x−k 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 ≤ 1 0 5 ) T (1≤T≤10^5) T(1≤T≤105), denoting the number of test cases.
For each test case, the first line contains two space-separated integers n n n and k k k ( 2 ≤ n ≤ 1 0 5 , 0 ≤ k ≤ 1 0 9 ) (2≤n≤10^5, 0≤k≤10^9) (2≤n≤105,0≤k≤109), where n n n is the number of days and k k k is the fluctuation limit.
The i i i-th line of the next n lines contains two space-separated integers l i l_i li and r i ( 0 ≤ l i ≤ r i ≤ 1 0 9 ) ri (0≤l_i≤r_i≤10^9) ri(0≤li≤ri≤109), which is Cuber QQ’s predicted interval in the i i i-th day. A prediction is believed to be correct if the stock price i i i-th day lies between l i l_i li and r i r_i ri, inclusive.
It is guaranteed that the sum of all n n n does not exceed 1 0 6 10^6 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,
a
1
,
a
2
,
…
,
a
n
a_1,a_2,…,an
a1,a2,…,an, where
l
i
≤
a
i
≤
r
i
(
1
≤
i
≤
n
)
l_i≤a_i≤r_i (1≤i≤n)
li≤ai≤ri(1≤i≤n) and
∣
a
i
−
a
i
+
1
∣
≤
k
(
1
≤
i
≤
n
−
1
)
|a_i−a_{i+1}|≤k (1≤i≤n−1)
∣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
思路
如果
i
i
i 是在
[
l
,
r
]
[l, r]
[l,r] 范围内, 那么
i
+
1
i + 1
i+1 必须要在
[
l
−
k
,
r
+
k
]
[l − k, r + k]
[l−k,r+k] 范围内.这是因为如果
i
+
1
i + 1
i+1 选了范围外的值,
i
i
i 就无解了.
这样可以从左往右, 把左边的约束带到右边.再从右往左做一遍.最后剩下的区间应该就是可行域.因为题目只要求一种方案, 全部选最低的即可.复杂度
O
(
n
)
O(n)
O(n).
#pragma GCC optimize(3,"Ofast","inline")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <set>
#include <map>
#include <algorithm>
#include <unordered_map>
using namespace std;
#define ls (rt<<1)
#define rs (rt<<1|1)
typedef long long ll;
template <typename T>
inline void read(T &x) {
x = 0;
static int p;
p = 1;
static char c;
c = getchar();
while (!isdigit(c)) {
if (c == '-')p = -1;
c = getchar();
}
while (isdigit(c)) {
x = (x << 1) + (x << 3) + (c - 48);
c = getchar();
}
x *= p;
}
template <typename T>
inline void print(T x) {
if (x<0) {
putchar('-');
x=-x;
}
static int cnt;
static int a[50];
cnt = 0;
do {
a[++cnt] = x % 10;
x /= 10;
} while (x);
for (int i = cnt; i >= 1; i--)putchar(a[i] + '0');
putchar(' ');
//puts("");
}
const int mod = 1e9+7;
const int inf = 0x3f3f3f3f;
const int maxn = 5e5+10;
int n,k;
int l[maxn],r[maxn];
inline void work() {
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; i++) {
scanf("%d%d", &l[i], &r[i]);
}
for (int i = 2; i <= n; i++) {
l[i] = max(l[i], l[i - 1] - k);
r[i] = min(r[i], r[i - 1] + k);
}
for (int i = n - 1; i >= 1; i--) {
l[i] = max(l[i], l[i + 1] - k);
r[i] = min(r[i], r[i + 1] + k);
}
int flag = 0;
for (int i = 1; i <= n; i++) {
if (l[i] > r[i]) {
flag = 1;
break;
}
}
if (!flag) {
puts("YES");
for (int i = 1; i <= n; i++) printf("%d ", l[i]);
printf("\n");
} else puts("NO");
}
int main() {
int T = 1;
scanf("%d", &T);
while (T--) {
work();
}
return 0;
}