uva12657纯双链模拟+白书代码(link函数是神器)

纯按结构体写的双向链,速度性能不够

#include<cstdio>
#include<cstring>
#include<stack>
#include<iostream>
#include<string>
using namespace std;
const int maxn = 100000 + 5;
struct node {
    int i;
    node* next;
    node* last;
}nodes[maxn];
int n, m, t, a, b;
bool inv;
int main() {
    while (scanf("%d%d", &n, &m)!=EOF)
    {
        memset(nodes, 0, sizeof(nodes));
        nodes[0].next = &nodes[1];
        nodes[n + 1].last = &nodes[n];
        for (int i = 1; i <= n; i++) {
            nodes[i].i = i;
            nodes[i].next = &nodes[i + 1];
            nodes[i].last = &nodes[i - 1];
        }
        inv = 0;
        while (m--) {
            scanf("%d", &t);

            if (inv && (t == 1 || t == 2)) {
                t = 3 - t;
            }
            if (t == 4) {
                inv = !inv;
            }
            else {
                scanf("%d%d", &a, &b);
            }
            node* aq = nodes[a].last;
            node* ap = nodes[a].next;
            node* bq = nodes[b].last;
            node* bp = nodes[b].next;
            if (t == 1) {
                aq->next = ap;
                ap->last = aq;
                nodes[a].last = bq;
                nodes[a].next = nodes + b;
                bq->next = nodes + a;
                nodes[b].last = nodes + a;
            }
            else if (t == 2) {
                aq->next = ap;
                ap->last = aq;
                nodes[a].last = nodes + b;
                nodes[a].next = bp;
                nodes[b].next = nodes + a;
                bp->last = nodes + a;
            }
            else if (t == 3) {
                aq->next = nodes + b;
                ap->last = nodes + b;
                bq->next = nodes + a;
                bp->last = nodes + a;
                nodes[a].next = bp;
                nodes[a].last = bq;
                nodes[b].next = ap;
                nodes[b].last = aq;
            }
            else if (t == 4) {
                inv = ~inv;
            }
        }
        // node head=nodes[0];
        int index=0;
        long long ans=0;
        // printf("%d\n", inv);
        if(0==inv){
            for (node* i = nodes; i->next; i = i->next){
                // printf("%d\t",i->i );
                if(index%2==1)ans+=i->i;
                index++;
            }
        }
        else{
            for (node* i = nodes+n+1; i->last; i = i->last){
                // printf("%d\t",i->i );
                if(index%2==1)ans+=i->i;
                index++;
            }
        }
        printf("\n%lld\n",ans);
    }
    return 0;
}

白书代码

#include<cstdio>
#include<algorithm>



using namespace std;
const int maxn = 100000 + 6;
int left[maxn],right[maxn],inv;
void link(int l,int r){
    right[l]=r;left[r]=l;
}
int main() {
    int n;

    int m,kase=0;
    while(scanf("%d%d",&n,&m)==2){
        for(int i=1;i<=n;i++){
            left[i]=i-1;
            right[i]=(i+1)%(n+1);
        }
        int b=0;

        right[0]=1;left[0]=n;

        int op,x,y,inv=0;
        while(m--){
            scanf("%d",&op);
            if(op==4)inv=!inv;
            else{
                scanf("%d%d",&x,&y);
                // if(op==3&&right[y]==x)swap(x,y);
                if(op!=3&&inv)op=3-op;
                if(op==1&&x==left[y])continue;
                if(op==2&&x==right[y])continue;
                int lx=left[x],rx=right[x],ly=left[y],ry=right[y];
                if(op==1){
                    link(lx,rx);link(ly,x);link(x,y);
                    lx=left[x],rx=right[x],ly=left[y],ry=right[y];
                }
                else if(op==2){
                    link(lx,rx);link(y,x);link(x,ry);
                }
                else if(op==3){
                    if(right[x]==y){link(lx,y);link(y,x);link(x,ry);}
                    else{link(lx,y);link(y,rx);link(ly,x);link(x,ry);}
                }
            }
        }
        long long ans=0;
        for(int i=1;i<=n;i++){
            b=right[b];
            if(i%2==1) ans+=b;
        }
        if(inv&&n%2==0) ans=(long long)n*(n+1)/2-ans;
        printf("Case %d: %lld\n",++kase,ans );
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值