题解 Loj6258 洛谷 ) 4032 火锅盛宴

题面太神奇了

用set记录当前火锅内的状态 , 每种食物数量

每个事件前更改食物状态(生/熟)

其他可以用树状数组很优雅的过掉

多组数据记得清空

#icnlude <set>
#include <cstdio>
#include
<cstring> #include <iostream> #include <algorithm> using namespace std; int read() { int s = 0, t = 1; char ch = getchar(); while (ch < '0' || ch > '9') { if (ch == '-') t = -1; ch = getchar(); } while (ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar(); return s * t; } int lowbit(int x){ return x & -x; } int T , n , Q; int s[200005] , a[200005] , tr[200005] , top , l;

//a记录熟食
set <pair<int ,int> > pot;//火锅内生的食物的状态 : 什么时候熟 , 编号 set <int> val[200005];//每种食物 void add(int x, int k){ a[x] += k; while (x <= top){ tr[x] += k; x += lowbit(x); } } int ask(int x){ int sum = 0; while (x){ sum += tr[x]; x -= lowbit(x); } return sum; } int getmin(){ if (!ask(top)) return 0; int b = l , pos = 0; while (~b) { if (!tr[pos | 1 << b]) pos |= 1 << b; b--; } return pos + 1; }//以上为树状数组 int main(){ T = read(); while (T--){ n = read(); memset(a , 0 , sizeof(a)); memset(tr, 0 , sizeof(tr)); pot.clear(); for(int i = 1; i <= n; i++) s[i] = read() , val[i].clear();//读入 && 清空 top = 1 , l = 0; while (top < n){ top <<= 1; l++; } Q = read(); while (Q--){ int t = read(), op = read(); while (!pot.empty() && (*pot.begin()).first <= t){//扫过熟的食物 int id = (*pot.begin()).second; add(id , 1);//扔进a pot.erase(pot.begin()); val[id].erase(val[id].begin());//火锅中删掉 }
if (op == 0){ int id = read(); pot.insert(make_pair (s[id] + t , id)); val[id].insert(t); } if (op == 1){ int food = getmin(); if (!food)//没有熟的 puts("Yazid is angry."); else{ add(food , -1); cout << food << endl; } } if (op == 2){ int id = read(); if (a[id]) puts("Succeeded!") , add(id , -1); else if( !val[id].empty()) cout << s[id] - t + *val[id].begin() << endl;//时间 else puts("YJQQQAQ is angry."); } if (op == 3){ int l = read() , r = read(); cout << ask(r) - ask(l - 1) << endl; } } } return 0; }

猜你喜欢

转载自www.cnblogs.com/treap/p/12234189.html
今日推荐