度度熊学队列(双端队列练习)
原題鏈接
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
分析:
- 1 u w val
- 2 u w
- 3 u v w(注意此時先讀入的v再讀入的w)
- 對于以上每種情況進行分析,一定有a(a == 1 / a == 2 / a == 3),u(隊列編號)和w(w == 1 / w == 0)兩個共同的變量,故這兩個變量在最開始就可以定義。而v,value在具體情況中才需要定義
- 要將提交語言從C++改成G++,才可以使用deque deq[n + 1]定義隊列,否則會提示如下錯誤
AC代碼
#include <deque> #include <cstdio> #include <iostream> #include <algorithm>using namespace std;int main() {int n,q;//多組數據while (scanf("%d%d",&n,&q) != EOF){deque<int> deq[n + 1];//多個空隊列for (int i = 0;i < q;i++){int a,u,w;scanf("%d%d%d",&a,&u,&w);if (a == 1)//a == 1里包含w == 0和w == 1兩種情況{int value;scanf("%d",&value);if (w == 0){deq[u].push_front(value);}else {deq[u].push_back(value);}}else if (a == 2)//包含w == 0和w == 1兩種情況{//判斷隊列非空if (!deq[u].empty()){if (w == 0){printf("%d\n",deq[u][0]);//詢問當前隊列最前元素deq[u].pop_front();//刪除最前元素}else{int len = (int)deq[u].size();printf("%d\n",deq[u][len - 1]);//詢問最后元素deq[u].pop_back();//刪除最后元素}}else printf("-1\n");}else{//a == 3時先讀入的v再讀入的w,故之前讀入的w其實是v的值int v;v = w;scanf("%d",&w);//讀入真正w的值if (w == 1 && deq[v].size() >= 2)//w == 1且隊列v中的元素至少為2才可以翻轉{reverse(deq[v].begin(),deq[v].end());}//v隊列非空,依次將隊列v的首元素插入隊列u的末尾//然后刪除隊列v的首元素while (!deq[v].empty()){deq[u].push_back( deq[v][0]);deq[v].pop_front();}}}}return 0; }總結
以上是生活随笔為你收集整理的度度熊学队列(双端队列练习)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Serverless Knative S
- 下一篇: 运营简史:一文读懂互联网运营的20年发展