1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
| #include<bits/stdc++.h> using namespace std; const int N = 5e5+5; struct edge{ int nxt,to; edge(){} edge(int _nxt,int _to){ nxt = _nxt,to = _to; } }e[100 * N]; int l[N],r[N],cnt,tot,pos[100 * N],head[100 * N],deg[100 * N],a[N],ls[100*N],rs[100*N]; void add_edge(int from,int to){
e[++cnt] = edge(head[from],to); head[from] = cnt; deg[to]++; } bool cmp(int a,int b){ return l[a] < l[b]; } void modify(int &now,int now_l,int now_r,int x,int y){ if(now){ ++tot;ls[tot] = ls[now],rs[tot] = rs[now]; now = tot; } else ++tot,now = tot; if(now_l == now_r){ add_edge(y,now); return; } int mid = (now_l + now_r)>>1; if(x <= mid) modify(ls[now],now_l,mid,x,y); if(x > mid) modify(rs[now],mid+1,now_r,x,y); if(ls[now]) add_edge(ls[now],now); if(rs[now]) add_edge(rs[now],now); } void query(int now,int now_l,int now_r,int l,int r,int x){ if(!now) return; if(l <= now_l && now_r <= r){ add_edge(now,x); return; } int mid = (now_l + now_r)>>1; if(l <= mid) query(ls[now],now_l,mid,l,r,x); if(r > mid) query(rs[now],mid+1,now_r,l,r,x); } int main(){
int n;scanf("%d",&n); for(int i=1; i<=2*n; i++){ int x;scanf("%d",&x); if(!l[x]) l[x] = i; r[x] = i; } for(int i=1; i<=n; i++) a[i] = i; sort(a+1,a+n+1,cmp); tot = n; int rt = 0; for(int i=1; i<=n; i++){ query(rt,1,2*n,1,r[a[i]]-1,a[i]); modify(rt,1,2*n,r[a[i]],a[i]); } queue<int> q1;priority_queue<int,vector<int>,greater<int> > q2; for(int i=1; i<=tot; i++){ if(!deg[i]){ if(i <= n) q2.push(i); else q1.push(i); } } while(!q1.empty() || !q2.empty()){ int now; if(!q1.empty()) now = q1.front(),q1.pop(); else now = q2.top(),q2.pop(); if(now <= n) printf("%d %d ",now,now); for(int i=head[now]; i; i=e[i].nxt){ int to = e[i].to; deg[to]--; if(!deg[to]){ if(to <= n) q2.push(to); else q1.push(to); } } } return 0; }
|