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=?”,而是”有一个含 ...
随机推荐
- Android 使用MySQL直接访问数据库
在实际项目中,一般很少直接访问MySQL数据库,一般情况下会通过http请求将数据传送到服务端,然后在服务端连接mysql数据库. 在android 中,会通过使用Jdbc 连接MySQL 服务器 p ...
- C# GridView使用方法
public void Point_databind(PointList pl) { chart1.Series.Clear(); //清空图表 Series s1 = new Series(); / ...
- 【技术累积】【点】【java】【25】Orderd
基础概念 Orderd是spring core中定义的一个接口,使用它以及相关的Comparator和@Order注解,可以实现对元素的排序. @Order 直接先说下@Order注解吧,使用场景较多 ...
- 类QQ账号生成阐述
具体需求如下: 数字账号从60000到9999999999(类似qq号一样的东东) 用户获取数字账号为随机分配,也可递加分配,需要符合如下规则 特殊账号需要保留,不能分配给用户,比如:112233(连 ...
- 2018年为什么要学习Python?Python还有前景吗?
近年来,Python一直是当仁不让的开发入行首选,无论是职位数量.就业广度还是使用排行都远超其他语言,而且Python语言接近自然语言,学习起来非常的轻松简便,因此也越来越受到人们的欢迎.进入到201 ...
- CVPR2016 Paper list
CVPR2016 Paper list ORAL SESSIONImage Captioning and Question Answering Monday, June 27th, 9:00AM - ...
- 转载:python 日期,季度,年份
# 这个data_matrix[:,dimen] <= thresh_val 内标会返回data_matrix当中的值符合条件的,返回为True # ret_array 中就会返回 下标为Tru ...
- My97DatePicker 开始日期不能大于 结束日期
My97DatePicker 日期控制,开始时间不能>结束时间,结束时间不能<开始时间 <li>日期:<input type="text" style ...
- JavaScript day4(条件语句和条件运算符)
1. 布尔值 布尔值要么是 true 要么是 false .它非常像电路开关, true 是“开”,false 是“关”.这两种状态是互斥的. 2. if 语句 if 语句用于在代码中做条件判断.关键 ...
- [luogu2594 ZJOI2009]染色游戏(博弈论)
传送门 Solution 对于硬币问题,结论是:当前局面的SG值等于所有背面朝上的单个硬币SG值的异或和 对于求单个背面朝上的硬币SG值...打表找规律吧 Code //By Menteur_Hxy ...