码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 6375 度度熊学队列 (链表模拟)

时间:2019-07-05 18:02:11      阅读:84      评论:0      收藏:0      [点我收藏+]

标签:双端队列   class   a*   als   algo   dell   get   frame   panel   

 

度度熊正在学习双端队列,他对其翻转和合并产生了很大的兴趣。

初始时有 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 度度熊学队列 (链表模拟)

标签:双端队列   class   a*   als   algo   dell   get   frame   panel   

原文地址:https://www.cnblogs.com/uid001/p/11139806.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!