1. 程式人生 > >度度熊學佇列 HDU

度度熊學佇列 HDU

度度熊正在學習雙端佇列,他對其翻轉和合併產生了很大的興趣。

初始時有 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’; }

  • 題解:直接用雙向佇列進行模擬即可,熟悉一下雙向佇列的用法。注意,我在這裡面把deque放在主函式外面,開一個1.5e5的佇列會顯示超記憶體(有點不明白130M的記憶體竟然存不下。1e7的陣列在256M的情況下都是能開的(這裡很無語)),然後放在主函式裡面竟然就a了。
#include<bits/stdc++.h>
using namespace std;
int n,q;
int main(){
    while(~scanf("%d %d",&n,&q)){
        deque<int> sn[n+1];
        while(q--){//對Q進行迴圈
            int k;scanf("%d",&k);
            if(k==1){//當k=1時為插入的情況
                int a,b,c;scanf("%d %d %d",&a,&b,&c);
                if(b){
                    sn[a].push_back(c);
                }else{
                    sn[a].push_front(c);
                }
            }else if(k==2){//當k=2時為輸出結果的情況
                int a,b;scanf("%d %d",&a,&b);
                if(sn[a].empty()){
                    printf("-1\n");continue;
                }
                if(b){
                    printf("%d\n",sn[a].at(sn[a].size()-1));
                    sn[a].pop_back();
                }else {
                    printf("%d\n",sn[a].at(0));
                    sn[a].pop_front();
                }
            }else if(k==3){//當k=3時為合併的情況
                int a,b,c;scanf("%d %d %d",&a,&b,&c);
                if(c==0){
                    while(!sn[b].empty()){
                        sn[a].push_back(sn[b].at(0));
                        sn[b].pop_front();
                    }
                }else{
                    reverse(sn[b].begin(),sn[b].end());
                    while(!sn[b].empty()){
                        sn[a].push_back(sn[b].at(0));
                        sn[b].pop_front();
                    }
                }
            }
        }
    }
    return 0;
}