题解:UVA1623 神龙喝水 Enter The Dragon
这能紫???那我要写个题解了。
按照题意,每次下雨操作都必须与一次喝水操作配对;并且,这次喝水必须在同一个湖的上一次下雨之后发生。因此,这次操作实际上规定了
考虑包含第一个
如果发现某个区间的左端点小于当前正在处理的
在实现上,可以用优先队列维护当前考虑范围内的所有区间右端点,总复杂度
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
vector<int> b[1000001];//b[i] 就是以 i 为左端点的所有右端点构成的集合
int a[1000001],lst[1000001],ans[1000001];
priority_queue<int,vector<int>,greater<int> > q;
int main() {
int T,n,m,i,j;
cin>>T;while(T--) {
cin>>n>>m;for(i=1;i<=n;i++) lst[i]=0;
for(i=1;i<=m;i++) {b[i].clear();ans[i]=0;}
for(i=1;i<=m;i++) {
cin>>a[i];
if(a[i]) {b[lst[a[i]]+1].push_back(i);lst[a[i]]=i;}
}
while(!q.empty()) q.pop();
for(i=1;i<=m;i++) {
for(j=0;j<b[i].size();j++) q.push(b[i][j]);
if(!q.empty()&&q.top()<i) break;
if(!a[i]&&!q.empty()) {ans[i]=a[q.top()];q.pop();}
}
if(!q.empty()) cout<<"NO\n";
else {
cout<<"YES\n";
for(i=1;i<=m;i++) if(!a[i]) cout<<ans[i]<<' ';
cout<<'\n';
}
}
}
::::