zoukankan      html  css  js  c++  java
  • CodePlus2017 12月月赛 div2火锅盛宴

    当时看到这道题感觉真是难过,我数据结构太弱啦。

    我们来看看需要求什么:

    1、当前熟了的食物的最小id

    2、当前熟了的食物中有没有编号为id的食物

    3、当前没熟的食物中有没有编号为id的食物

    4、当前没熟的食物中编号为id的食物最接近煮熟的还需要多久才会熟

    5、当前熟了的食物中编号在[l,r]之间的有多少个

    我们需要维护的操作是:

    1、往当前的锅里面加一个编号为id的生食物

    2、每个时刻锅里面哪些生的食物要变熟

    3、吃掉(删除)一个熟了的食物


    感觉这种题真考人做题的毅力,求的东西好杂感觉脑子里都乱套了。

    我用了4个multiset+1个树状数组来水这道题。

    4个multiset:

    Hn               : 存int,当前没熟的的食物的id(按照id顺序)

    Hn2             : 存结构体,当前没熟的食物的id和熟的时间(按照熟的时间顺序)

    now[maxn]  : 存int,now[i]是id为i的未熟食物的熟的时间(按照熟的时间顺序)

    Hd               : 存int,当前熟了的食物的id(按照id顺序)

    剩下还有一个树状数组用来求id在一个区间的熟了的食物的个数的。

    感觉非常不优秀,但是当时剩下时间不多,就没有怎么优化。

    注意multiset如果直接erase(x)会把所有值为x的都删掉,只删一个需要先find,再删。(感谢Achen)

    //Serene
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    #include<set>
    using namespace std;
    const int maxn=1e5+10,maxm=5e5+10;
    int n,m,T,s[maxn];
    
    struct Node{
    	int id,time;
    	Node() {}
    	Node(int id,int time):id(id),time(time){}
    	bool operator < (const Node& b) const{
    		return time < b.time;
    	}
    };
    
    multiset<int> Hn;
    multiset<Node> Hn2;
    multiset<Node>::iterator it;
    multiset<int>::iterator it2;
    multiset<int> Hd;
    multiset<int> now[maxn];
    
    int aa;char cc;
    int read() {
    	aa=0;cc=getchar();
    	while(cc<'0'||cc>'9') cc=getchar();
    	while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
    	return aa;
    }
    
    int sz[maxn];
    void chge(int pos,int x) {
    	while(pos<=n) {
    		sz[pos]+=x;
    		pos+=pos&-pos;
    	}
    }
    
    int q(int pos) {
    	int rs=0;
    	while(pos) {
    		rs+=sz[pos];
    		pos-=pos&-pos;
    	}
    	return rs;
    }
    
    int main() {
    	T=read(); int t,op,l,r,x;
    	while(T--) {
    		Hn.clear(); Hn2.clear(); Hd.clear();
    		for(int i=1;i<=n;++i) now[i].clear();
    		memset(sz,0,sizeof(sz));
    		n=read(); 
    		for(int i=1;i<=n;++i) s[i]=read();
    		m=read();
    		while(m--) {
    			t=read(); op=read();
    			while(!Hn2.empty()) {
    				it=Hn2.begin();
    				if(it->time>t) break;
    				x=it->id;
    				it2=Hn.find(x);
    				Hn.erase(it2);
    				Hd.insert(x);
    				Hn2.erase(it);
    				chge(x,1);
    				while(!now[x].empty()) {
    					it2=now[x].begin();
    					if(*it2>t) break;
    					now[x].erase(it2);
    				}
    			}
    			if(op==0) {
    				x=read();
    				Hn2.insert(Node(x,t+s[x]));
    				Hn.insert(x);
    				now[x].insert(t+s[x]);
    			}
    			else if(op==1) {
    				if(Hd.empty()) {
    					printf("Yazid is angry.
    ");
    					continue;
    				}
    				it2=Hd.begin();
    				printf("%d
    ",*it2);
    				chge(*it2,-1);
    				Hd.erase(it2);
    			}
    			else if(op==2) {
    				x=read();
    				if((it2=Hd.find(x))!=Hd.end()) {
    					printf("Succeeded!
    ");
    					chge(*it2,-1);
    					Hd.erase(it2);
    				}
    				else if(Hn.find(x)!=Hn.end()) {
    					it2=now[x].begin();
    					printf("%d
    ",*it2-t);
    				}
    				else printf("YJQQQAQ is angry.
    ");
    			}
    			else if(op==3) {
    				l=read(); r=read();
    				printf("%d
    ",q(r)-q(l-1));
    			}
    		}
    	}
    	return 0;
    }
    

      

     

  • 相关阅读:
    linux 进程学习笔记-运行新进程
    linux 进程学习笔记-进程状态
    linux 进程学习笔记-进程调度
    linux 进程学习笔记-进程退出/终止进程
    linux 进程学习笔记-暂停进程
    linux 进程学习笔记-进程跟踪
    linux 进程学习笔记-等待子进程结束
    linux 进程学习笔记-进程pipe管道
    linux 进程学习笔记-named pipe (FIFO)命名管道
    linux 进程学习笔记-进程信号sigal
  • 原文地址:https://www.cnblogs.com/Serene-shixinyi/p/8111331.html
Copyright © 2011-2022 走看看