1. 程式人生 > >csu 1982:小M的移動硬盤(雙向鏈表)

csu 1982:小M的移動硬盤(雙向鏈表)

所有 create space ios 硬盤 put tin 雙鏈表 ostream

Description

最近小M買了一個移動硬盤來儲存自己電腦裏不常用的文件。但是他把這些文件一股腦丟進移動硬盤後,覺得這些文件似乎沒有被很好地歸類,這樣以後找起來豈不是會非常麻煩?
小M最終決定要把這些文件好好歸類,把同一類地移動到一起。所以現在小M有了這幾種操作:
1 u 表示把編號為u的文件放到最上面
2 u 表示把編號為u的文件放到最下面
3 u v 表示把編號為u的文件放到編號為v的文件的後面
已知在最開始的時候,1號文件到n號文件從上往下排布
現在小M已經給出了他所進行的所有操作,你能告訴他操作之後的序列是會變成什麽樣子嗎?

Input

第一行為一個數字T(T<=10)表示數據組數
第二行為兩個數字n、m(1<=n,m<=300000)表示序列長度和小M的操作次數
接下來m行每行兩個或三個數字,具體含義見題面
保證數據合法

Output

輸出一行表示小M操作結束後的序列

Sample Input

1
10 5
1 5
2 3
2 6
3 4 8
3 1 3

Sample Output

5 2 7 8 4 9 10 3 1 6

第一次用鏈表做題,用一個數組保存每個數字所在的地址就可以實現O(1)查找了,坑了我很久,我開始建了一個循環雙鏈表,結果死活WA(好像問題是出在第二步移動操作了),然後我將尾指針棄之不用,每次都是插在尾指針前面,然後就AC了.

#include<iostream>
#include<cstdio>
#include<algorithm>
#include 
<string.h> #include <math.h> using namespace std; const int N =300005; typedef long long LL; typedef struct LNode{ int data; struct LNode *next,*pre; }*LinkList,LNode; LinkList id[N]; LinkList L,tail; void create(int n,LinkList &L,LinkList &tail){ LinkList p,r; r = new
LNode; tail = new LNode; L->next = L->pre = L; L = r; int i= 1; while(i<=n){ p = new LNode; p->data = i; id[i] = p; i++; r->next = p; p->pre = r; r = p; } r->next = tail; tail->pre = r; } void HeadInsert(LinkList &L,LinkList &p){ p->next = L->next; L->next = p; p->pre = L; p->next->pre = p; } void TailInsert(LinkList &tail,LinkList &p){ tail->pre->next = p; p->pre = tail->pre; p->next = tail; tail->pre = p; } void InsertUV(LinkList &p,LinkList &q){ q->next->pre = p; p->pre = q; p->next = q->next; q->next = p; } void Travel(LinkList L){ LNode *p = L->next; while(p!=tail){ printf("%d ",p->data); p = p->next; } } int main() { int tcase; scanf("%d",&tcase); int n,m; while(tcase--) { L = new LNode; scanf("%d %d",&n,&m); create(n,L,tail); int op,u,v; while(m--){ scanf("%d",&op); if(op==1){ scanf("%d",&u); LinkList p = id[u]; if(L->next ==p) continue; p->pre->next = p->next; p->next->pre = p->pre; HeadInsert(L,p); } if(op==2){ scanf("%d",&u); LinkList p = id[u]; if(p==tail) continue; p->pre->next = p->next; p->next->pre = p->pre; TailInsert(tail,p); //Travel(L); } if(op==3){ scanf("%d %d",&u,&v); LinkList p = id[u],q = id[v]; if(p==q) continue; p->pre->next = p->next; p->next->pre = p->pre; InsertUV(p,q); } } Travel(L); LinkList p=L,q; while(p!=tail){ q = p; p=p->next; delete q; } delete tail; printf("\n"); } return 0; }

csu 1982:小M的移動硬盤(雙向鏈表)