hdu 6375 度度熊学队列 (链表模拟)
Posted uid001
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 6375 度度熊学队列 (链表模拟)相关的知识,希望对你有一定的参考价值。
度度熊正在学习双端队列,他对其翻转和合并产生了很大的兴趣。
初始时有 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 被清空。
初始时有 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 被清空。
维护双向链表模拟, 删除的时候要注意判断删除后的结点在哪一侧.
#include <iostream> #include <algorithm> #include <cstdio> #include <math.h> #include <set> #include <map> #include <queue> #include <string> #include <string.h> #include <bitset> #define REP(i,a,n) for(int i=a;i<=n;++i) #define PER(i,a,n) for(int i=n;i>=a;--i) #define hr putchar(10) #define pb push_back #define lc (o<<1) #define rc (lc|1) #define mid ((l+r)>>1) #define ls lc,l,mid #define rs rc,mid+1,r #define x first #define y second #define io std::ios::sync_with_stdio(false) #define endl ‘\n‘ #define DB(a) (REP(__i,1,n) cout<<a[__i]<<‘ ‘;hr;) using namespace std; typedef long long ll; typedef pair<int,int> pii; const int P = 1e9+7, INF = 0x3f3f3f3f; ll gcd(ll a,ll b) return b?gcd(b,a%b):a; ll qpow(ll a,ll n) ll r=1%P;for (a%=P;n;a=a*a%P,n>>=1)if(n&1)r=r*a%P;return r; ll inv(ll x)return x<=1?1:inv(P%x)*(P-P/x)%P; inline int rd() int x=0;char p=getchar();while(p<‘0‘||p>‘9‘)p=getchar();while(p>=‘0‘&&p<=‘9‘)x=x*10+p-‘0‘,p=getchar();return x; //head const int N = 1e7+10; int n, q, clk; int head[N], tail[N]; struct _ int l,r,v; a[N]; int tim[N],ti; void upd(int x) if (tim[x]!=ti) tim[x]=ti,head[x]=tail[x]=0; void addL(int id, int v) upd(id); a[++clk].v = v; if (!head[id]) head[id] = tail[id] = clk; a[clk].l = a[clk].r = -1; else if (a[head[id]].l==-1) a[head[id]].l = clk; a[clk].l = -1; a[clk].r = head[id]; else a[head[id]].r = clk; a[clk].r = -1; a[clk].l = head[id]; head[id] = clk; void addR(int id, int v) upd(id); a[++clk].v = v; if (!tail[id]) head[id] = tail[id] = clk; a[clk].l = a[clk].r = -1; else if (a[tail[id]].l==-1) a[tail[id]].l = clk; a[clk].l = -1; a[clk].r = tail[id]; else a[tail[id]].r = clk; a[clk].r = -1; a[clk].l = tail[id]; tail[id] = clk; void delL(int id) upd(id); if (!head[id]) return puts("-1"),void(); printf("%d\n", a[head[id]].v); if (a[head[id]].l==-1&&a[head[id]].r==-1) head[id] = tail[id] = 0; return; int t = head[id]; if (a[t].l==-1) head[id] = a[t].r; else head[id] = a[t].l; if (a[head[id]].r==t) a[head[id]].r = -1; else a[head[id]].l = -1; void delR(int id) upd(id); if (!tail[id]) return puts("-1"),void(); printf("%d\n", a[tail[id]].v); if (a[tail[id]].l==-1&&a[tail[id]].r==-1) head[id] = tail[id] = 0; return; int t = tail[id]; if (a[t].l==-1) tail[id] = a[t].r; else tail[id] = a[t].l; if (a[tail[id]].l==t) a[tail[id]].l = -1; else a[tail[id]].r = -1; void reverse(int id) upd(id); swap(head[id],tail[id]); void merge(int x, int y) if (x==y) return; upd(x),upd(y); if (!head[y]) return; if (!head[x]) head[x] = head[y]; tail[x] = tail[y]; else if (a[tail[x]].l==-1) a[tail[x]].l = head[y]; else a[tail[x]].r = head[y]; if (a[head[y]].l==-1) a[head[y]].l = tail[x]; else a[head[y]].r = tail[x]; tail[x] = tail[y]; head[y] = tail[y] = 0; void read(int &x) scanf("%d",&x); int main() while (~scanf("%d%d", &n, &q)) ++ti; while (q--) int op,u,v,w; read(op),read(u),read(v); if (op==1) read(w); if (v==0) addL(u,w); else addR(u,w); else if (op==2) if (v==0) delL(u); else delR(u); else read(w); if (w) reverse(v); merge(u,v);
以上是关于hdu 6375 度度熊学队列 (链表模拟)的主要内容,如果未能解决你的问题,请参考以下文章