题意:n个湖,每个湖都装满了水。不久的将来会有暴雨,在接下来的m天内,每天要么不下雨,要么恰好忘一个湖里下暴雨。如果这个湖里已经装满了水,将会引发水灾。没了避免水灾,神龙可以在每个不下雨的天里喝干一个湖的水(也可以不喝)。如果以后再往这个干枯的湖里下暴雨,湖会重新被填满,但不会引发水灾。神龙应当如何喝水才能避免水灾?n<=1e6,.<=1e6
思路:贪心,因为要优化时间复杂度,所以用set集合,本身有序,且可以二分查找。如果某天湖下雨,那么查找它上一次满候是否有不下雨的天让神龙喝水
#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define INF 0x3f3f3f3f
#define mod 1000000007;
using namespace std;
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
const int maxn = 1e6 + 2;
set<int> day;
int n,m,x,ans[maxn],full[maxn];
int main()
{
int T; scanf("%d",&T);
while(T--)
{
day.clear();
bool sign = true;
scanf("%d%d",&n,&m);
memset(ans,0,sizeof(ans));
memset(full,0,sizeof(full));
for(int i = 0;i < m;i++)
{
scanf("%d",&x);
if(!sign) continue;
if(!x) day.insert(i);//没下雨,闲置天数+1
else
{
ans[i] = -1;
set<int>::iterator it = day.lower_bound(full[x]);
if(it == day.end()) sign = false;
else
{
ans[*it] = x;
full[x] = i;
day.erase(*it);
}
}
}
if(!sign) printf("NO\n");
else
{
bool fir = false;
printf("YES\n");
for(int i = 0;i < m;i++)
{
if(ans[i] >= 0)
{
if(!fir)
{
printf("%d",ans[i]);
fir = true;
}
else printf(" %d",ans[i]);
}
}
printf("\n");
}
}
return 0;
}