题目链接
思路:
把n个食物的需求need求出来。
每次都选择一个 a[i]-need[i] 最大的食物i
如果这个是非负的 就可以,否则必死。。
那么把喜欢的食物包含i的这批人 放在最后 ,无论前面的人怎么放 这些都是合法的。
然后把这批人喜欢的另一个食物的需求减减。
一直执行这个过程,直到m个人都搞完。
所有过程可以用线段树完成(全局最大值查询,单点更新)
最后倒序输出即可。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e5 + 10;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
int n,m,a[N],L[N],R[N],dx[N];
#define mid (l+r>>1)
#define ls o<<1
#define rs o<<1|1
int t[N<<2];
vector<int>v[N];
void build(int o,int l,int r){
if(l==r){
t[o]=a[l]-dx[l];
return;
}
build(ls,l,mid);
build(rs,mid+1,r);
t[o]=max(t[ls],t[rs]);
}
int get(int o,int l,int r){
if(l==r)return l;
if(t[ls]>t[rs])return get(ls,l,mid);
return get(rs,mid+1,r);
}
void up(int o,int l,int r,int x,int d){
if(l==r){
t[o]+=d;
return ;
}
if(x<=mid)up(ls,l,mid,x,d);
else up(rs,mid+1,r,x,d);
t[o]=max(t[ls],t[rs]);
}
int vis[N];
int main() {
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=m;i++){
cin>>L[i]>>R[i];
v[L[i]].pb(i);
v[R[i]].pb(i);
dx[L[i]]++;
dx[R[i]]++;
}
build(1,1,n);
vector<int>ans;
while(ans.size()<m){
int now=get(1,1,n);
if(dx[now]>a[now])return cout<<"DEAD\n",0;
up(1,1,n,now,-1e9);
for(auto k:v[now]){
if(vis[k])continue;
ans.pb(k);
vis[k]=1;
if(L[k]!=now)up(1,1,n,L[k],1),dx[L[k]]--;
else up(1,1,n,R[k],1),dx[R[k]]--;
}
}
cout<<"ALIVE\n";
reverse(ans.begin(),ans.end());
for(auto k:ans)cout<<k<<' ';
return 0;
}