uva 12657(双向链表)

一定要注意swap(x, y),x, y可能相邻!

#include <cstdio>
#define N 100005
#define ll long long
int n, m;
struct node{
  int l, r;
  node() : l(0), r(0) {}
  node(int l_, int r_) : l(l_), r(r_) {}
}num[N];

void init()
{
    for(int i = 0; i <= n + 1; i++)
        num[i].l = i - 1, num[i].r = i + 1;
}

void move2left(int x, int y)
{
    if(num[y].l == x) return ;
    int l, r;
    l = num[x].l, r = num[x].r;
    num[l].r = r, num[r].l = l;
    l = num[y].l, r = y;
    num[x].r = r, num[x].l = l;
    num[l].r = x, num[r].l = x;
}

void move2right(int x, int y)
{
    if(num[y].r == x) return ;
    int l, r;
    l = num[x].l, r = num[x].r;
    num[l].r = r, num[r].l = l;
    l = y,        r = num[y].r;
    num[x].r = r, num[x].l = l;
    num[l].r = x, num[r].l = x;
}

void Swap(int x, int y)
{
    int xl, xr, yl, yr;
    if(num[x].r == y) {
        xl = num[x].l, yr = num[y].r;
        num[xl].r = y, num[yr].l = x;
        num[y].l = xl, num[y].r = x;
        num[x].l = y, num[x].r = yr;
    }
    else if(num[x].l == y) {
        xr = num[x].r, yl = num[y].l;
        num[xr].l = y, num[yl].r = x;
        num[y].l = x, num[y].r = xr;
        num[x].l = yl, num[x].r = y;
    }
    else {
    xl = num[x].l, xr = num[x].r;
    yl = num[y].l, yr = num[y].r;
    num[xl].r = y, num[xr].l = y;
    num[yl].r = x, num[yr].l = x;
    num[x].l = yl, num[x].r = yr;
    num[y].l = xl, num[y].r = xr;
    }

}

int main()
{
    //freopen("out.txt", "w", stdout);
    int cases = 0;
    while(~scanf("%d%d", &n, &m))
    {
        cases++;
        init();
        int op, res = 1;
        for(int i = 1; i <= m; i++)
        {
            scanf("%d", &op);
            int x, y;
            if(op < 4) scanf("%d%d", &x, &y);
            if((op == 1 && res) || (op == 2 && !res))
                move2left(x, y);
            else if((op == 2 && res) || (op == 1 && !res))
                move2right(x, y);
            else if(op == 3)
                Swap(x, y);
            else res = !res;
        }
        ll sum = 0;
        if(res) {
            int t = num[0].r, c = 0;
            while(c < n) {
                c++;
                if(c % 2 == 1) sum += (ll)t;
                //printf("%d***\n", t);
                t = num[t].r;
            }
        }
        else {
            int t = num[n + 1].l, c = 0;
            //printf("%d***\n", t);
            while(c < n) {
                c++;
                if(c % 2 == 1) sum += (ll)t;
                //printf("%d***\n", t);
                t = num[t].l;
            }
        }
        printf("Case %d: %lld\n", cases, sum);
    }
    return 0;
}

 

你可能感兴趣的:(双向链表)