HDU 6375(双端队列 ~)

题意是有至多150000个双端队列,400000次简单操作,直接开会导致内存超限,所以用 STL 中的 map 和 deque ,而读入过大已经在题目中有所说明,直接用已经给出的快速读入即可。要注意的是在两个队列合并时,要用 insert 函数,直接一个一个操作会超时(自己对双端队列的 STL 还是不够熟悉......)代码如下:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N = 150005;
 4 map<int, deque<int> > q;
 5 void read(int &x){
 6     char ch = getchar();x = 0;
 7     for (; ch < '0' || ch > '9'; ch = getchar());
 8     for (; ch >='0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
 9 }
10 int main()
11 {
12     int a,n,m,u,v,w,val;
13     while(~scanf("%d%d",&n,&m))
14     {
15         for(int i = 1; i <= n; i++)
16             q[i].clear();
17         while(m--)
18         {
19             read(a);
20             if(a == 1)
21             {
22                 read(u);
23                 read(w);
24                 read(val);
25                 if(w == 0) q[u].push_front(val);
26                 else if(w == 1) q[u].push_back(val);
27             }
28             else if(a == 2)
29             {
30                 read(u);
31                 read(w);
32                 if(q[u].empty())
33                 {
34                     puts("-1");
35                     continue;
36                 }
37                 if(w == 0)
38                 {
39                     printf("%d
",q[u].front());
40                     q[u].pop_front();
41                 }
42                 else if(w == 1)
43                 {
44                     printf("%d
",q[u].back());
45                     q[u].pop_back();
46                 }
47             }
48             else if(a == 3)
49             {
50                 read(u);
51                 read(v);
52                 read(w);
53                 if(w == 0)
54                 {
55                     q[u].insert(q[u].end(),q[v].begin(),q[v].end());
56                     q[v].clear();
57                 }
58                 else if(w == 1)
59                 {
60                     q[u].insert(q[u].end(),q[v].rbegin(),q[v].rend());
61                     q[v].clear();
62                 }
63             }
64         }
65 
66     }
67     return 0;
68 }
View Code

一般来说 STL 用法简单,但是其中会带有许多与题目本身无关的功能,而用时也就会多出很多,用数组去模拟一些 STL 中的标准模板可以大幅减少不必要的耗时,本题中手写的双端队列用时不到用 STL 的一半,代码如下:

  1 #include<stdio.h>
  2 void read(int &x){
  3     char ch = getchar();x = 0;
  4     for (; ch < '0' || ch > '9'; ch = getchar());
  5     for (; ch >='0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
  6 }
  7 struct record
  8 {
  9     int value;
 10     record *next;
 11     record *pre;
 12 }stack1[500010];
 13 int cnt;
 14 class listqueue
 15 {
 16 public:
 17     record *head,*tail;
 18     void pop()
 19     {
 20         if(!empty())
 21         {
 22             printf("%d
",tail->value);
 23             tail = tail->pre;
 24             if(tail == 0)
 25                 head = 0;
 26             else
 27                 tail->next = 0;
 28         }
 29         else
 30             puts("-1");
 31     }
 32     bool empty()
 33     {
 34         return head == 0;
 35     }
 36     void shift()
 37     {
 38         if(!empty())
 39         {
 40             printf("%d
",head->value);
 41             head = head->next;
 42             if(head == 0)
 43                 tail = 0;
 44             else
 45                 head->pre = 0;
 46         }
 47         else
 48             puts("-1");
 49     }
 50     void clear()
 51     {
 52         head = tail = 0;
 53     }
 54     void unshift(int n)
 55     {
 56         stack1[cnt].value = n;
 57         stack1[cnt].next = head;
 58         stack1[cnt].pre = 0;
 59         if(head)
 60             head->pre = &stack1[cnt];
 61         head = &stack1[cnt];
 62         if(tail == 0)
 63             tail = head;
 64         cnt++;
 65     }
 66     void push(int n)
 67     {
 68         stack1[cnt].value = n;
 69         stack1[cnt].next = 0;
 70         stack1[cnt].pre = tail;
 71         if(tail)
 72             tail->next = &stack1[cnt];
 73         tail = &stack1[cnt];
 74         if(head == 0)
 75             head = tail;
 76         cnt++;
 77     }
 78     void append(listqueue &v)
 79     {
 80         if(v.head)
 81         {
 82             if(head == 0)
 83                 head = v.head;
 84             else
 85             {
 86                 tail->next = v.head;
 87                 v.head->pre = tail;
 88             }
 89             tail = v.tail;
 90             v.clear();
 91         }
 92     }
 93     void reverse()
 94     {
 95         if(empty())
 96             return;
 97         record *temp,*temp1;
 98         for(temp = tail; temp != head; temp = temp->next)
 99         {
100             temp1 = temp->next;
101             temp->next = temp->pre;
102             temp->pre = temp1;
103         }
104         temp1 = temp->next;
105         temp->next = temp->pre;
106         temp->pre = temp1;
107         head = tail;
108         tail = temp;
109     }
110 }rec[150100];
111 int main()
112 {
113     int n,q,u,v,w,val;
114     int type,i;
115     while(~scanf("%d%d",&n,&q))
116     {
117         cnt = 1;
118         for(i = 1; i <= n; i++)
119         {
120             rec[i].clear();
121         }
122         while(q--)
123         {
124             read(type);
125             if(type == 1)
126             {
127                 read(u);
128                 read(w);
129                 read(val);
130                 if(w == 0)
131                     rec[u].unshift(val);
132                 else
133                     rec[u].push(val);
134             }
135             else if(type == 2)
136             {
137                 read(u);
138                 read(w);
139                 if(w == 0)
140                     rec[u].shift();
141                 else
142                     rec[u].pop();
143             }
144             else
145             {
146                 read(u);
147                 read(v);
148                 read(w);
149                 if(w == 1)
150                     rec[v].reverse();
151                 rec[u].append(rec[v]);
152             }
153         }
154     }
155     return 0;
156 }
View Code
日后若能有更好的想法,再来完善。 希望看到的大神不吝赐教 orz
原文地址:https://www.cnblogs.com/Taskr212/p/9460752.html