UVA 12657

双向链表 
///双向链表---节点
///如果数据结构上的某一个操作很耗时,有时可以用加标记的方式处理,而不需要真的去执行那个操作,
///但同时,该数据结构的所有其他操作都要考虑这个操作
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cstdlib>

using namespace std;
#define maxn 100005
int Right[100005],Left[100005];

void link(int L, int R)///辅助函数是两个节点相互连接
{
    Right[L]=R;
    Left[R]=L;
}

int main()
{
    int n,m;
    int op;
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=1; i<=n; i++)
        {
            Left[i]=i-1;
            Right[i]=(i+1)%(n+1);
        }
        Right[0]=1;
        Left[0]=n;

        int inv=0;
        int X,Y;
        while(m--)
        {
            cin>>op;
            if(op==4)
                inv=1;
            else
            {
                cin>>X>>Y;
                if(op==3&&Right[Y]==X)  swap(X,Y);///交换后使得Y保证在X的右边,利于后面的统一交换操作
                if(op!=3&&inv)  op=3-op;
                if(op==1&&Right[X]==Y)  continue;
                if(op==2&&Right[Y]==X)  continue;

                int LX=Left[X], RX=Right[X], LY=Left[Y], RY=Right[Y];///这一步至关重要,倘若不使用这一步,在连接节点的过程中,原始值会发生改变,会导致之后系列的连接出错
                if(op==1)
                {
                    link(LX,RX);
                    link(X,Y);
                    link(LY,X);
                }
                else if(op==2)
                {
                    link(LX,RX);
                    link(Y,X);
                    link(X,RY);
                }
                else if(op==3)
                {
                    if(RX==Y)
                    {
                        link(LX,Y);
                        link(Y,X);
                        link(X,RY);
                    }
                    else
                    {
                        link(LX,Y);
                        link(Y,RX);
                        link(LY,X);
                        link(X,RY);
                    }
                }
            }
        }
        int t=0;
        long long ans=0;///防止数据溢出
        for(int i=1; i<=n; i++)
        {
            t=Right[t];
            if(i%2)
                ans+=t;
        }
        if(inv&&n%2==0) ans=(long long)n*(n+1)/2-ans;
                cout<<ans<<endl;
    }

    return 0;
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值