「CodePlus 2017 12 月赛」火锅盛宴(模拟+树状数组)

Posted Sakits

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了「CodePlus 2017 12 月赛」火锅盛宴(模拟+树状数组)相关的知识,希望对你有一定的参考价值。

  1A,拿来练手的好题

  用一个优先队列按煮熟时间从小到大排序,被煮熟了就弹出来。

  用n个vector维护每种食物的煮熟时间,显然是有序的。

  用树状数组维护每种煮熟食物的数量。

  每次操作前把优先队列里煮熟时间<=当前时间的弹出,BIT上+1。

  每次0操作把食物塞进优先队列和vector

  每次1操作先看看树状数组里有没有数,没有输出angry,有的话在树状数组上二分找到最小的数。

  每次2操作先看看树状数组里有没有这一种数,有的话输出并-1,没有的话看看vector有没有,有的话输出时间差,没有的话输出angry。

  没了,写得行云流水。

技术分享图片
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<queue>
#include<vector>
#define ll long long
using namespace std;
const int maxn=500010;
struct poi{int pos, tim;};
priority_queue<poi>q;
bool operator<(poi a, poi b){return a.tim>b.tim;}
int n, Q, mx, t, ty, x, l, r, T;
int tree[1<<20], fir[maxn], s[maxn];
vector<int>v[maxn];
inline void read(int &k)
{
    int f=1; k=0; char c=getchar();
    while(c<0 || c>9) c==- && (f=-1), c=getchar();
    while(c<=9 && c>=0) k=k*10+c-0, c=getchar();
    k*=f;
}
inline void add(int x, int delta){for(;x<=mx;x+=x&-x) tree[x]+=delta;}
inline int query(int x){int sum=0; for(;x;x-=x&-x) sum+=tree[x]; return sum;}
inline void yazid()
{
    if(!tree[mx]) {puts("Yazid is angry."); return;}
    int l=0, r=mx, k=1;
    while(l<r)
    {
        int mid=(l+r)>>1;
        if(tree[mid]>=k) r=mid;
        else k-=tree[mid], l=mid+1;
    }
    add(l, -1); printf("%d\n", l);
    return;
}
inline void yjqqaq(int t, int id)
{
    if(query(id)-query(id-1)) {puts("Succeeded!"); add(id, -1); return;}
    if(v[id].size()==fir[id]) {puts("YJQQQAQ is angry."); return;}
    printf("%d\n", v[id][fir[id]]-t); return;
}
inline void clear()
{
    memset(tree, 0, (mx+1)<<2);
    memset(fir, 0, (n+1)<<2);
    while(!q.empty()) q.pop();
    for(int i=1;i<=n;i++) v[i].clear();
}
int main()
{
    read(T);
    while(T--)
    {
        read(n); mx=1; while(mx<=n) mx<<=1; clear();
        for(int i=1;i<=n;i++) read(s[i]);
        read(Q);
        for(int i=1;i<=Q;i++)
        {
            read(t); read(ty);
            while(!q.empty())
            {
                poi now=q.top();
                if(now.tim<=t) q.pop(), add(now.pos, 1), fir[now.pos]++;
                else break; 
            }
            if(!ty) read(x), q.push((poi){x, t+s[x]}), v[x].push_back(t+s[x]);
            else if(ty==1) yazid();
            else if(ty==2) read(x), yjqqaq(t, x);
            else read(l), read(r), printf("%d\n", query(r)-query(l-1));
        }
    }
}
View Code

以上是关于「CodePlus 2017 12 月赛」火锅盛宴(模拟+树状数组)的主要内容,如果未能解决你的问题,请参考以下文章

CodePlus2017 12月月赛 div2火锅盛宴

「CodePlus 2017 12 月赛」白金元首与独舞

LibreOJ#6259. 「CodePlus 2017 12 月赛」白金元首与独舞

LIbreOJ#6256. 「CodePlus 2017 12 月赛」可做题1

走进矩阵树定理--「CodePlus 2017 12 月赛」白金元首与独舞

「CodePlus 2017 12 月赛」可做题2(矩阵快速幂+exgcd)