code+12月月赛 火锅盛宴
时间限制: 2.0 秒
空间限制: 512 MB
题目背景
SkyDec和YJQQQAQ都是Yazid的好朋友。他们都非常喜欢吃火锅。有一天,他们聚在一起,享受一场火锅盛宴。
题目描述
在这场火锅盛宴中,有一个麻辣浓汤锅底的火锅和n种食物,每种食物数量都是无限的。我们用1至n将这些食材编号。
每种食物煮熟所需要的时间不同,第i种食物煮熟需要si单位时间。这表示如果你在第T个时刻将一个食物i下到火锅里,那么它会在第T+si个时刻被煮熟,并且此后一直会延续被煮熟的状态,直到它被拿走为止。
Yazid和YJQQQAQ的口味不同:YJQQQAQ觉得所有食物的好吃程度都是相同的;而Yazid则觉得没有两种食材的好吃程度是相同的,并且,巧合的是,编号越小的食物Yazid越喜欢吃。可怜的SkyDec由于不能吃辣,所以只能帮Yazid和YJQQQAQ煮食物。
整个火锅盛宴持续109单位时间。在整个盛宴中,三位好朋友除了谈笑风生之外,最重要的事当然就是吃东西了。在任意整数时刻,都有可能发生下列4种事件中的任意一种,我们用0至3之间的整数op描述事件类型:
0 id
:表示SkyDec往火锅里下了一个编号为id的食物。1
:Yazid在锅内搜寻熟了的且最喜欢吃的食物,并拿走一个这种食物。特别地,如果锅里没有熟了的食物,那么Yazid会很愤怒。2 id
:YJQQQAQ在锅内搜寻编号为id的食物:如果锅里不存在该种食物,则YJQQQAQ会很愤怒;如果锅里存在熟了的该食物,则YJQQQAQ会取走一个并食用;如果锅里只有未煮熟的该种食物,那么YJQQQAQ会希望知道最接近煮熟的该种食物(即锅内存在时间最长的该种食物)还需要多少时间被煮熟。3 l r
:馋涎欲滴的SkyDec想知道,锅里编号在[l,r]之间的且熟了的食物总共有多少个。
整个火锅晚宴中共发生了Q个事件,且没有任意两个事件在同一时刻发生。
他们的好朋友Flvze想知道这场火锅晚宴中发生的所有事,所以请你告诉她。
输入格式
从标准输入读入数据。
本题包含多组数据,输入的第一行为一个正整数T,表示数据组数。接下来依次描述每组数据,对于每组数据:
第一行一个正整数n,表示食物的种类数。
第二行n个用空格隔开的正整数s1,s2,…,sn,描述每种食物煮熟需要的时间。
第三行一个正整数Q,表示事件的数目。
接下来Q行,每行若干个用空格隔开的非负整数,描述一个事件。先是两个整数t,op,分别表示发生事件的时间以及事件的类型。如果op=0或op=2,则接下来1个正整数id,意义见题目描述
;如果op=1,则接下来没有其他数;如果op=3,则接下来2个正整数l,r,意义见题目描述
。
我们保证t按输入顺序严格递增。
我们保证1≤t≤109,0≤op≤3,1≤id≤n,1≤l≤r≤n。
输出格式
对于每个op≠0的操作,输出一行表示答案。对于不同的op,需要输出的内容如下:
- 对于op=1,如果Yazid成功取走食物,则输出他取走食物的编号;否则输出"Yazid is angry."(不含引号,下同)。
- 对于op=2,如果YJQQQAQ成功取走食物,则输出"Succeeded!";否则,如果锅里有未煮熟的该类食物,输出最接近煮熟的该种食物还需要多少时间被煮熟;否则,输出"YJQQQAQ is angry."。
- 对于op=3,输出锅内编号在指定范围内的熟食的数量。
输出到标准输出。
样例1输入
1
2
1 100
10
1 0 2
2 0 1
3 2 1
4 2 2
5 2 1
200 0 1
201 3 1 2
202 1
203 1
204 1
样例1输出
Succeeded!
97
YJQQQAQ is angry.
2
1
2
Yazid is angry.
子任务
测试点编号 | n≤ | Q≤ | 特殊约定 | 测试点分值 |
---|---|---|---|---|
1 | 500 | 1000 | 无 | 8 |
2-3 | 10 | 300,000 | 无 | 6 |
4-5 | 100,000 | 所有si=1 | 8 | |
6-7 | 所有si都相同 | 11 | ||
8-9 | op≠3 | 7 | ||
10-11 | 无 | 12 | ||
12-13 | 500,000 | 2 |
对于所有数据,保证T≤4,保证n≤100,000,Q≤500,000,1≤si≤108。
大意:有N种食物,编号越小越好吃,三个操作:(1)往火锅里放食物(2)查找最喜欢的而且熟了的食物(3)输出编号在[L,R]之间的熟的食物的数量
大意只是大意,题目要求还有好多细节,请移步题目描述和输出格式。
题解:
这题确实是一个很有意思的数据结构题,考场上想开N+1个set搞一搞,但是没有时间写这题了。
当然,大多数人写的是三个set的方法
后来出题人说三个set能过,因为他没有卡。
正解是
先将食物按照熟的时间从小到大排序,这样在枚举时间的时候就方便找到该下锅的食物或者此时刚熟的食物了。
树状数组+链表。
在按时间顺序枚举事件的时候,用树状数组维护前 k 种食物中熟的个数,用链表维护已经放下但是没有熟的食物。
一个食物下锅后先放入链表,发现链表表头的食物熟了,就取出表头,更新树状数组,查找和拿出食物的时候在树状数组里操作就行了。
值得一提的是树状数组的upper_bound(v)操作:找出 最小的 大于v的前缀和,也是O(logN)的时间复杂度。详见代码。
贴一份高仿某位大神的代码(我几乎背下来的)
/*
Welcome Hacking
Wish You High Rating
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<string>
using namespace std;
int read(){
int xx=0,ff=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')ff=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){xx=(xx<<3)+(xx<<1)+ch-'0';ch=getchar();}
return xx*ff;
}
const int maxn=100010,maxm=500010;
int N,Q,s[maxn],arg1[maxm],arg2[maxm],t[maxm],op[maxm];
int id[maxm],cnt,head[maxn],tail[maxn];
struct BIT{
int b[maxn];
inline int lowbit(int x)
{return x&-x;}
void clear()
{memset(b,0,sizeof(b));}
void upd(int x,int v){
for(;x<=N;x+=lowbit(x))
b[x]+=v;
}
int query(int x){
int re=0;
for(;x;x-=lowbit(x))
re+=b[x];
return re;
}
int upper_bound(int v){
int x=0,sum=0;
for(int i=(1<<16);i;i>>=1)
if(x+i<=N&&sum+b[x+i]<=v)
sum+=b[x+=i];
return x+1;
}
}bit;
bool mycmp(int xx,int yy)
{return t[xx]+s[arg1[xx]]<t[yy]+s[arg1[yy]];}
struct Node{
int data,next;
}node[maxm];
int node_cnt;
void add(int x,int val){
if(!head[x])
head[x]=tail[x]=++node_cnt;
else{
node[tail[x]].next=++node_cnt;
tail[x]=node_cnt;
}
node[node_cnt].data=val;
}
void remove(int x){
bit.upd(x,1);
head[x]=node[head[x]].next;
if(!head[x])
tail[x]=0;
}
int main(){
//freopen("in","r",stdin);
//freopen("out","w",stdout);
for(int T=read();T;T--){
N=read();cnt=0;node_cnt=0,bit.clear();
memset(head,0,sizeof(head));
memset(tail,0,sizeof(tail));
memset(node,0,sizeof(node));
for(int i=1;i<=N;i++)
s[i]=read();
Q=read();
for(int i=1;i<=Q;i++){
t[i]=read(),op[i]=read();
if(op[i]==0)arg1[i]=read(),id[++cnt]=i;
else if(op[i]==1);
else if(op[i]==2)arg1[i]=read();
else arg1[i]=read(),arg2[i]=read();
}
sort(id+1,id+1+cnt,mycmp);
int q=1;
for(int i=1;i<=Q;i++){
while(q<=cnt&&t[id[q]]+s[arg1[id[q]]]<=t[i]){
remove(arg1[id[q]]);
q++;
}
if(op[i]==0)
add(arg1[i],t[i]+s[arg1[i]]);
else if(op[i]==1){
int temp=bit.upper_bound(0);
if(temp==N+1)
printf("Yazid is angry.\n");
else{
bit.upd(temp,-1);
printf("%d\n",temp);
}
}
else if(op[i]==2){
if(bit.query(arg1[i])-bit.query(arg1[i]-1)){
bit.upd(arg1[i],-1);
printf("Succeeded!\n");
}
else if(head[arg1[i]])
printf("%d\n",node[head[arg1[i]]].data-t[i]);
else
printf("YJQQQAQ is angry.\n");
}
else
printf("%d\n",bit.query(arg2[i])-bit.query(arg1[i]-1));
}
}
return 0;
}
code+12月月赛 火锅盛宴的更多相关文章
- CodePlus2017 12月月赛 div2可做题2
11月的月赛错过了,来打12月月赛,由于很(zi)想(ji)拿(tai)衣(ruo)服(la),所以去打div2. T1是一个sb模拟,但是机房全卡死在这道语文题上了,基本上弄了一个半小时,T2可以秒 ...
- CodePlus2017 12月月赛 div2火锅盛宴
当时看到这道题感觉真是难过,我数据结构太弱啦. 我们来看看需要求什么: 1.当前熟了的食物的最小id 2.当前熟了的食物中有没有编号为id的食物 3.当前没熟的食物中有没有编号为id的食物 4.当前没 ...
- CSU 2018年12月月赛 B 2214: Sequence Magic
Description 有一个1到N的自然数序列1,2,3,...,N-1,N. 我们对它进行M次操作,每次操作将其中连续的一段区间 [Ai,Bi][Ai,Bi] (即第Ai个元素到第Bi个元素之间的 ...
- 安恒X计划12月月赛
ezweb 主要是序列化问题.没有PHP环境,在线运行的.实例化对象之后修改一下file.然后echo输出序列化的结果.不过下面有一个正则检查.数字前加一个+,影响了正则的匹配,但是对于序列化的还原没 ...
- CSU 2018年12月月赛 H(2220): Godsend
Description Leha somehow found an array consisting of n integers. Looking at it, he came up with a t ...
- CSU 2018年12月月赛 G(2219): Coin
Description 有这样一个众所周知的问题: 你面前有7个硬币,其中有一个劣质的(它比正常的硬币轻一点点),你有一个天平,问需要你需要使用天平多少次能保证找到那个劣质的硬币. 众所周知的算法是: ...
- CSU 2018年12月月赛 F(2218): Finding prime numbers
Description xrdog has a number set. There are 95 numbers in this set. They all have something in com ...
- CSU 2018年12月月赛 D 2216 : Words Transformation
Description There are n words, you have to turn them into plural form. If a singular noun ends with ...
- CSU 2018年12月月赛 A 2213: Physics Exam
Description 高中物理老师总认为给学生文本形式的问题比给纯计算形式的问题要求更高.毕竟,学生首先得阅读和理解问题. 因此,他们描述一个问题不像”U=10V,I=5A,P=?”,而是”有一个含 ...
随机推荐
- 搜索条件两个时间,通过php数组排序,保证select语句between时间 前小后大
//搜索条件两个时间,通过数组排序,保证select语句between时间 前小后大 $sort_array=[$_POST['clockDate1'],$_POST['clockDate2']]; ...
- PHP 之转换excel表格中的经纬度
<?php set_time_limit(0); include './plugin/PHPExcel/PHPExcel.php'; include './plugin/PHPExcel/PHP ...
- Xftp 5 和 Xshell 5 基本使用方法
软件介绍: (1)Xshell: 一个强大的安全终端模拟软件,它支持SSH1, SSH2, 以及Microsoft Windows 平台的 TELNET 协议.Xshell通过互联网可以连接到远程的服 ...
- Python3爬取前程无忧数据分析工作并存储到MySQL
1.导入包import requests #取数from lxml import etree #用xpath解析import pymysql #连接数据库import chardet #自动获取编码2 ...
- Android之手机振动和振铃
一.振动的实现1.使用振动所需的权限 <uses-permission android:name="android.permission.VIBRATE" />2.相关 ...
- 【模板】dijkstra
洛谷 4779 #include<cstdio> #include<cstring> #include<algorithm> #include<queue&g ...
- Mysql学习总结(41)——MySql数据库基本语句再体会
1.数据定义语言(DDL):定义和管理数据对象,比如建立数据库.数据表 数据操作语言(DML):用于操作数据库对象中的包含的数据. 数据查询语言(DQL):用于查询数据库对象中包含的数据,能够对表进行 ...
- Girls Love 233
Girls Love 233 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) P ...
- 洛谷 P4198 BZOJ 2957 楼房重建
题目描述 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题,我们考虑这些事件发生在一个 ...
- Lifting the Stone 计算几何 多边形求重心
Problem Description There are many secret openings in the floor which are covered by a big heavy sto ...