题目链接

Problem Description
度度熊正在学习双端队列,他对其翻转和合并产生了很大的兴趣。

初始时有 N 个空的双端队列(编号为 1 到 N ),你要支持度度熊的 Q 次操作。

①1 u w val 在编号为 u 的队列里加入一个权值为 val 的元素。(w=0 表示加在最前面,w=1 表示加在最后面)。

②2 u w 询问编号为 u 的队列里的某个元素并删除它。( w=0 表示询问并操作最前面的元素,w=1 表示最后面)

③3 u v w 把编号为 v 的队列“接在”编号为 u 的队列的最后面。w=0 表示顺序接(队列 v 的开头和队列 u 的结尾连在一起,队列v 的结尾作为新队列的结尾), w=1 表示逆序接(先将队列 v 翻转,再顺序接在队列 u 后面)。且该操作完成后,队列 v 被清空。

Input
有多组数据。

对于每一组数据,第一行读入两个数 N 和 Q。

接下来有 Q 行,每行 3~4 个数,意义如上。

N≤150000,Q≤400000

1≤u,v≤N,0≤w≤1,1≤val≤100000

所有数据里 Q 的和不超过500000

Output
对于每组数据的每一个操作②,输出一行表示答案。

注意,如果操作②的队列是空的,就输出−1且不执行删除操作。

Sample Input
2 10
1 1 1 23
1 1 0 233
2 1 1
1 2 1 2333
1 2 1 23333
3 1 2 1
2 2 0
2 1 1
2 1 0
2 1 1
Sample Output
23
-1
2333
233
23333
提示
由于读入过大,C/C++ 选手建议使用读入优化。
一个简单的例子:
void read(int &x){
char ch = getchar();x = 0;
for (; ch < '0' || ch > '9'; ch = getchar());
for (; ch >='0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
}
题意
实现双向队列,要求的功能有:维护N个双向队列,在首/尾部进行插入/删除,以及将一个队列顺序/逆序附到另一个队列尾部,并且清空原序列。
分析
为了避免双向队列颠倒的复杂度,其实完全可以忽略节点的先后顺序,把双向队列想象成一个所有节点入度出度都为1的连通图,那么对链表所有的操作,都可以看作是在图上的加边减边操作,因此,只需要维护每个节点的两条边就行了。
具体的来说,队列加点=连通图中新增一个节点并连一条边到指定的边界;队列删点=图删边;队列附加=两个连通图之间加一条边,连接两个边界点。
因为总是在队列首尾操作,也就是图的边界点,因此记录下每个连通图的两个边界,每次只需要找到图上边界点的相邻的点进行操作,并在操作完后,更新连通图的边界点。
注意
空队列不能被删除,但可以添加一个非空队列到他的后面

代码

#include<stdio.h>
#include<memory.h>
int head[], tail[];
int n, q;
int id = ;
//双向链表节点
struct thing
{
int v;
int t1, t2;//不必记录顺序
thing() :v(), t1(-), t2(-) {}
void conn(int x) {
if (t1 == -)t1 = x;
else t2 = x;
}
void brk(int x) {
if (t1 == x)t1 = -;
else if (t2 == x)t2 = -;
}
}node[]; //头部插入
void qaddf(int qid, int nid) {
if (head[qid] == -) {
head[qid] = nid;
tail[qid] = nid;
}
else {
int h = head[qid];
node[nid].conn(h);
node[h].conn(nid);
head[qid] = nid;
}
} //尾部插入
void qadde(int qid, int nid) {
if (head[qid] == -) {
head[qid] = nid;
tail[qid] = nid;
}
else {
int t = tail[qid];
node[nid].conn(t);
node[t].conn(nid);
tail[qid] = nid;
}
} //头部删除
int delf(int qid) {
int s = head[qid];
if (s == -)return -; if (head[qid] == tail[qid]) {
head[qid] = -; tail[qid] = -;
return node[s].v;
} int next = (node[s].t1 != - ? node[s].t1 : node[s].t2);
node[next].brk(s);
head[qid] = next;
return node[s].v;
} //尾部删除
int dele(int qid) {
int s = tail[qid];
if (s == -)return -; if (head[qid] == tail[qid]) {
head[qid] = -; tail[qid] = -;
return node[s].v;
} int next = (node[s].t1 != - ? node[s].t1 : node[s].t2);
node[next].brk(s);
tail[qid] = next;
return node[s].v;
} //顺序连接
void linkf(int q1, int q2) {
if (head[q2] == -)return;
if (head[q1] != -) {
node[tail[q1]].conn(head[q2]);
node[head[q2]].conn(tail[q1]);
tail[q1] = tail[q2]; }
else
{
head[q1] = head[q2];
tail[q1] = tail[q2];
}
head[q2] = -; tail[q2] = -;
} //逆序连接
void linke(int q1, int q2) {
if(head[q2]==-)return;
if (head[q1] != -) {
node[tail[q1]].conn(tail[q2]);
node[tail[q2]].conn(tail[q1]);
tail[q1] = head[q2]; }
else
{
tail[q1] = head[q2];
head[q1] = tail[q2];
}
head[q2] = -; tail[q2] = -;
} //简易读外挂
void getn(int&x) {
x = ;
char ch;
do ch = getchar(); while (ch<'' || ch>'');
do { x = x * + ch - ''; ch = getchar(); } while ('' <= ch&&ch <= '');
} int main() {
int ipt[];
while (~scanf("%d %d", &n, &q)) {
id = ;
memset(head, -, sizeof head);
memset(tail, -, sizeof tail);
for (int i = ; i<q; ++i) {
getn(ipt[]);
switch (ipt[]) {
case ://在队列ipt[1]中插入ipt[3]到头/尾部(ipt[2]=0/1)
getn(ipt[]); getn(ipt[]); getn(ipt[]);
node[++id].v = ipt[]; node[id].t1 = -; node[id].t2 = -;
if (ipt[] == ) {
qaddf(ipt[], id);
}
else {
qadde(ipt[], id);
}
break;
case ://在队列ipt[1]中删除头/尾部(ipt[2]=0/1)
getn(ipt[]); getn(ipt[]);
if (ipt[] == ) {
printf("%d\n", delf(ipt[]));
}
else {
printf("%d\n", dele(ipt[]));
}
break;
case ://将队列ipt[2]正/反接到ipt[1]后面(ipt[3]=0/1)
getn(ipt[]); getn(ipt[]); getn(ipt[]);
if (ipt[] == )
linkf(ipt[], ipt[]);
else
linke(ipt[], ipt[]);
break;
default:
break;
}
}
}
}
#define tree \
\
*\
**\
***\
||

hdu 6375 百度之星 度度熊学队列的更多相关文章

  1. hdu6375 度度熊学队列

    度度熊学队列 题目传送门 解题思路 STL大法好.直接用deque,但是N的范围很大,如果直接开那么多的deque会爆内存,所以用map< int, deque< int>>, ...

  2. hdu 6375 度度熊学队列 (链表模拟)

    度度熊正在学习双端队列,他对其翻转和合并产生了很大的兴趣.  初始时有 N 个空的双端队列(编号为 1 到 N ),你要支持度度熊的 Q 次操作. ①1 u w val 在编号为 u 的队列里加入一个 ...

  3. 【2018百度之星初赛(A)】1002 度度熊学队列

    题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=6375 Knowledge Point: STL - map:https://www.cnblogs.c ...

  4. 2018 “百度之星”程序设计大赛 - 初赛(A)度度熊学队列 list rope

    c++ list使用 #include <cstdio> #include <cstdlib> #include <cmath> #include <cstr ...

  5. 2018百度之星初赛(A)2 度度熊学队列

    思路: 记录一下c++ stl中的双向链表list的各种用法. https://blog.csdn.net/fanyun_01/article/details/56881515 实现: #includ ...

  6. 2018百度之星初赛A轮 度度熊学队列

    注意:刚开始用数组存deque<int> qa[MAX]会爆内存 需要改用map<int, deque<int> > qa优化 不明觉厉 #include<b ...

  7. 2017百度春招<度度熊买帽子的问题>

    题目: 度度熊想去商场买一顶帽子,商场里有N顶帽子,有些帽子的价格可能相同.度度熊想买一顶价格第三便宜的帽子,问第三便宜的帽子价格是多少? 数组中找到第三小的数字  注意边界条件 用STL中的set来 ...

  8. hdu 6119 …&&百度之星 T6

    小小粉丝度度熊 Problem Description 度度熊喜欢着喵哈哈村的大明星——星星小姐. 为什么度度熊会喜欢星星小姐呢? 首先星星小姐笑起来非常动人,其次星星小姐唱歌也非常好听. 但这都不是 ...

  9. HDU - 6383 百度之星2018初赛B 1004 p1m2(二分答案)

    p1m2  Accepts: 1003  Submissions: 4595  Time Limit: 2000/1000 MS (Java/Others)  Memory Limit: 131072 ...

随机推荐

  1. 20155328 《Java程序设计》实验一(Java开发环境的熟悉) 实验报告

    20155328 <Java程序设计>实验一(Java开发环境的熟悉) 实验报告 一.实验内容及步骤 (一)使用JDK编译.运行简单的java程序 命令行下的程序开发: 打开windows ...

  2. 成都Uber优步司机奖励政策(4月12日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  3. python3工作环境部署+spyder3+jupyter notebook

    1.python3安装 1)官网去下载python3.7版本,双击安装,只要注意勾选写到PATH就行,其它直接NEXT. 2)安装完成,CMD键入 python 回车,跳出python界面就是成功. ...

  4. Jlink v8仿真器在64位系统上刷固件

    1. 安装软件sam-ba_2.16.exe.本次主要是Jlink v8在64位系统下面的刷固件方法. 2. J-link通过USB连接至电脑,短接PCB上标号为ERASE的焊盘5秒,断开ERASE两 ...

  5. C#课后小作业

    有关C#基础的练手 跟大家一起分享下 1.让用户输入一个100以内的数 打印1-100之间所有的数,用户输入的数除外 2.让用户输入一个100以内的数 打印1-这个数之间所有的数的和 3.使用一个fo ...

  6. Supervisor4.0和python2.7的crit问题,导致python进程阻塞

    1.问题原因 Supervisor高版本在守护python2.7的服务时,会crit并报错并倒至进程阻塞(python进程存在,但不在运行)的问题,一般会和字符集有关系 <type 'excep ...

  7. 面试之HTTP基础(不断完善中)

    目录 1. HTTP状态码 2.Cookie和Session Cookie Session 3.短连接与长连接 4.HTTPs 加密 5.Http和https的区别 6.HTTP/1.0 与 HTTP ...

  8. java计算工龄

    计算工龄原则:若是2000-10-12作为开始工作时间,则到下一年的2001-10-13算为一年.有个bug,不满一年的工龄是错误的. import java.util.Date;import jav ...

  9. redis主从配置+sentinel哨兵

    redis主从配置+sentinel哨兵 1:编译环境准备 1.1环境确认 Redis是一个开源.支持网络.基于内存.键值对存储数据库,使用ANSI C编写.所以在搭建Redis服务器时需要C语言的编 ...

  10. div不设置高度背景颜色或外边框不能显示的解决方法

    在使用div+css进行网页布局时,如果外部div有背景颜色或者边框,而不设置其高度,在浏览时出现最外层Div的背景颜色和边框不起作用的问题. 大体结构<div class="oute ...