HDU6375-度度熊学队列 双向链表

度度熊学队列

Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1206    Accepted Submission(s): 393


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 个数,意义如上。

N150000,Q400000

1u,vN,0w1,1val100000

所有数据里 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++ 选手建议使用读入优化。 
 
思路:注意删除一个节点后,指向被删除节点的指针置NULL。
 
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string>
#include <string.h>
#include <new>
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define maxn 150009
#define maxq 400009
using namespace std;

struct node_data
{
    node_data *l, *r;
    int data;
};
struct node_que
{
    node_data *head, *tail;
};
void addhead(node_que &q, int a) {
    if (!q.head) {
        q.head = new node_data;
        q.head->data = a;
        q.head->l = q.head->r = NULL;
        q.tail = q.head;
    }
    else {
        node_data *xin = new node_data;
        xin->data = a;
        xin->r = q.head;
        xin->l = NULL;
        q.head->l = xin;
        q.head = xin;
    }
}
void addtail(node_que &q, int a) {
    if (!q.tail) {
        q.tail = new node_data;
        q.tail->data = a;
        q.tail->l = q.tail->r = NULL;
        q.head = q.tail;
    }
    else {
        node_data *xin = new node_data;
        xin->data = a;
        xin->l = q.tail;
        xin->r = NULL;
        q.tail->r = xin;
        q.tail = xin;
    }
}
int delehead(node_que &q) {
    if (!q.head) return -1;
    int v = q.head->data;
    if (q.tail == q.head) {
        node_data *a = q.tail;
        q.tail = q.head = NULL;
        free(a);
        return v;
    }
    q.head = q.head->r;
    free(q.head->l);
    q.head->l = NULL;
    return v;
}
int deletail(node_que &q) {
    if (!q.tail) return -1;
    int v = q.tail->data;
    if (q.tail == q.head) {
        node_data *a = q.tail;
        q.tail = q.head = NULL;
        free(a);
        return v;
    }
    q.tail = q.tail->l;
    free(q.tail->r);
    q.tail->r = NULL;
    return v;
}
void merge(node_que &u, node_que &v, int w) {
    if (!v.tail) return;
    if (w) {
        node_data *ch = v.head, *ch1;
        while (ch)
        {
            ch1 = ch->l; ch->l = ch->r; ch->r = ch1;
            ch = ch->l;
        }
        ch = v.head; v.head = v.tail; v.tail = ch;
    }
    if (u.tail) {
        u.tail->r = v.head;
        v.head->l = u.tail;
    }
    else {
        u.head = v.head;
    }
    u.tail = v.tail;
    v.tail = v.head = NULL;
}
void clearque(node_que &q) {
    while (q.head != q.tail)
    {
        q.head = q.head->r;
        free(q.head->l);
    }
    free(q.head);
    q.head = q.tail = NULL;
}

int n, q;
int cz, u, v, w, val;
node_que qq[maxn];

int main() {
    while (scanf("%d%d",&n,&q)!=EOF)
    {
        for(int i = 1; i <= q; i++){
            scanf("%d%d", &cz, &u);
            if (cz == 1) {
                scanf("%d%d", &w, &val);
                if (w) addtail(qq[u], val);
                else addhead(qq[u], val);
            }
            else if (cz == 2) {
                scanf("%d", &w);
                int ans;
                if (w) ans = deletail(qq[u]);
                else ans = delehead(qq[u]);
                printf("%d\n", ans);
            }
            else {
                scanf("%d%d", &v, &w);
                merge(qq[u], qq[v], w);
            }
        }
        for (int i = 1; i <= n; i++) {
            clearque(qq[i]);
        }
    }
    return 0;
}

 

posted @ 2018-08-12 10:13  casccac  阅读(316)  评论(0编辑  收藏  举报