1. 程式人生 > 實用技巧 >F - Fluctuation Limit

F - Fluctuation Limit

https://vjudge.net/contest/389195#problem/F

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 followingnndays. He shall make his prediction by filling a table withnnintervals, theii-th of which is the predicted interval
[li,ri][li,ri]at theii-th day. If allnnprices 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 bothkk, which is an integer. That means, if the stock price at the
ii-th day isxx, the price at thei+1i+1-th day is at mostx+kx+kand at leastxkx−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 the11million 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.

InputThe input starts with an integerTT(1T1051≤T≤105), denoting the number of test cases.

For each test case, the first line contains two space-separated integersnnandkk(2n1052≤n≤105,0k1090≤k≤109), wherennis the number of days andkkis the fluctuation limit.

Theii-th line of the nextnnlines contains two space-separated integersliliandriri(0liri1090≤li≤ri≤109), which is Cuber QQ's predicted interval in theii-th day. A prediction is believed to be correct if the stock priceii-th day lies betweenliliandriri, inclusive.

It is guaranteed that the sum of allnndoes not exceed106106.
OutputFor each test case, first output a single lineYESorNO, that states whether Cuber QQ will win the 1 million price.

IfYES, in the next line, output a possible price series,a1,a2,,ana1,a2,…,an, whereliairili≤ai≤ri(1in1≤i≤n) and|aiai+1|k|ai−ai+1|≤k(1in11≤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

Sponsor

題意:每次能在一個能夠變換的區間變化,找區間

思路:

  正反兩邊掃描, 把左邊的約束帶到右邊,反過來滿足後面的方法決定前面的改變.

  同時滿足正反兩面變化的區間,最後剩下的為可行域(選最低的

程式碼:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<bitset>
#include<cassert>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<deque>
#include<iomanip>
#include<list>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#include <vector>
#include <iterator>
#include <utility>
#include <sstream>
#include <limits>
#include <numeric>
#include <functional>
using namespace std;
#define gc getchar()
#define mem(a) memset(a,0,sizeof(a))
#define debug(x) cout<<"debug:"<<#x<<" = "<<x<<endl;

#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int,int> pii;
typedef char ch;
typedef double db;

const double PI=acos(-1.0);
const double eps=1e-6;
const int inf=0x3f3f3f3f;
const int maxn=1e5+10;
const int maxm=100+10;
const int N=1e6+10;
const int mod=1e9+7;

ll L[maxn] = {0};
ll R[maxn] = {0};
int main()
{
	ll l[maxn] = {0};
	ll r[maxn] = {0};
	ll n = 0 , k = 0;
	bool flag = 1;
	
    int T = 0;
    cin >> T;
    while(T--)
    {
        flag = 1;
        cin >> n >> k;
        for(int i = 0;i<n;i++)
        {
            cin >> L[i] >> R[i];
        }
        l[0] = L[0];
        r[0] = R[0];
        
        
        for(int i = 1;i<n;i++)
        {
            r[i] = min(R[i] , r[i-1] + k);
            l[i] = max(L[i] , l[i-1] - k);
            if(r[i] < l[i])
            {
            	flag = 0;
			}
        }
        for(int i = 1;i<n;i++)
        {
            r[n-1-i] = min(r[n-1-i] , r[n-i] + k);
            l[n-1-i] = max(l[n-1-i] , l[n-i] - k);
            if(r[i] < l[i])
			{
            	flag = 0;
			}
        }
        
        if(flag)
        {
            cout << "YES" <<endl;
            for(int i = 0;i<n;i++)
            {
          		cout << r[i];
            	if(i < n-1)
            	{
            		cout<<" ";
				}
			}
            cout <<endl;
        }
        else
        {
        	cout << "NO" <<endl;
		}
    }
    return 0;
}

/*
2
3 1
1 6
2 5
3 6
2 3
1 5
10 50
*/