大致思路:
这道题就是对于每一天的变化,都有一个能够变换的区间,只要找到这个区间,就可以解决本题
区间我们通过正反两边扫描找到,正着扫的时候能够满足前面的变化决定后面的变化,反着扫的时候就满足后面的变化决定前面的变化
所以只有同时满足正反两面变化的区间,才是最后成为正确答案的区间
正着扫的时候,这个区间的左边界和右边界分别满足:
反着扫的时候,区间的边界要满足:
代码如下:
#include<bits/stdc++.h> #define mem(a) memset(a,0,sizeof(a)) #define forn(i,n) for(int i=0;i<n;++i) #define for1(i,n) for(int i=1;i<=n;++i) #define IO std::ios::sync_with_stdio(false); std::cin.tie(0) #define ll long long #define inf 0x3f3f3f3f using namespace std; const int maxn=1e5+50; const int mod=1e9+7; ll l[maxn]; ll r[maxn]; ll up[maxn]; ll down[maxn]; int main() { IO; int T; cin>>T; while(T--) { ll n,k; bool flag=false; cin>>n>>k; for1(i,n) { cin>>l[i]>>r[i]; } down[1]=l[1]; up[1]=r[1]; for(int i=2; i<=n; ++i) { up[i]=min(r[i],up[i-1]+k); down[i]=max(l[i],down[i-1]-k); if(up[i]<down[i]) flag=true; } for(int i=n-1; i>=1; --i) { up[i]=min(up[i],up[i+1]+k); down[i]=max(down[i],down[i+1]-k); if(up[i]<down[i]) flag=true; } if(flag) cout<<"NO\n"; else { cout<<"YES\n"; for(int i=1; i<=n; ++i) if(i==1) cout<<up[i]; else cout<<" "<<up[i]; cout<<"\n"; } } return 0; }
原文:https://www.cnblogs.com/bethebestone/p/13512012.html