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 被清空。

 

 

 

维护双向链表模拟, 删除的时候要注意判断删除后的结点在哪一侧.

 

#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 度度熊学队列 (链表模拟)的主要内容,如果未能解决你的问题,请参考以下文章

2018百度之星初赛(A)1002 度度熊学队列

度度熊学队列

度度熊学队列

1002—度度熊学队列

HDU6375双端队列

2018 “百度之星”程序设计大赛 - 初赛(A)度度熊学队列 list rope