题目连接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=47066
利用链表换位置时间复杂度为1的优越性,同时也考虑到使用实际的链表对一个数字进行定位需要扫一遍,时间复杂度难以承受,因此使用数组模拟双向链表。
易错点:1.要对特殊位置进行处理,例如xy相邻的情况
2.注意链表头和尾可能在任意一个操作中变化,要进行检查
#include <bits/stdc++.h> using namespace std; const int Max=1e5+10; typedef long long LL; #define scan(x) scanf("%d",&x); struct node { int data,p[2]; }lists[Max]; int n,m,head,tail,swi; //!swi--left,swi--right int lm,rm; int Scan() { int res=0,ch,flag=0; if((ch=getchar())=='-') flag=1; else if(ch>='0'&&ch<='9') res=ch-'0'; while((ch=getchar())>='0'&&ch<='9') res=res*10+ch-'0'; return flag?-res:res; } inline void index(int x,int &x1,int &x2,int &x3) { x2=x; x1=lists[x2].p[!swi]; x3=lists[x2].p[swi]; } void check(int x) { if(x<1||x>n) return; if(lists[x].p[!swi]==lm) head=x; if(lists[x].p[swi]==rm) tail=x; } void movesl(int x,int y) { int x1,x2,x3,y1,y2,y3; index(x,x1,x2,x3);index(y,y1,y2,y3); if(x1==y2) return; lists[y3].p[!swi]=y1; lists[y1].p[swi]=y3; lists[y2].p[!swi]=x1;lists[x1].p[swi]=y2; lists[y2].p[swi]=x2;lists[x2].p[!swi]=y2; check(y1);check(x1);check(x3);check(x2);check(y2);check(y3); } void movesr(int x,int y) { int x1,x2,x3,y1,y2,y3; index(x,x1,x2,x3);index(y,y1,y2,y3); if(x3==y2) return; lists[y3].p[!swi]=y1; lists[y1].p[swi]=y3; lists[y2].p[!swi]=x2;lists[x2].p[swi]=y2; lists[y2].p[swi]=x3;lists[x3].p[!swi]=y2; check(y1);check(x1);check(x3);check(x2);check(y2);check(y3); } void swaps1(int x1,int x,int y,int y1) { lists[x].p[!swi]=y; lists[x].p[swi]=y1; lists[y].p[!swi]=x1; lists[y].p[swi]=x; lists[x1].p[swi]=y; lists[y1].p[!swi]=x; check(x1);check(x);check(y);check(y1); } void swaps(int x,int y) { int x1,x2,x3,y1,y2,y3; index(x,x1,x2,x3);index(y,y1,y2,y3); if(x3==y2) {swaps1(x1,x2,y2,y3);return;} if(y3==x2) {swaps1(y1,y2,x2,x3);return;} lists[x2].p[!swi]=y1;lists[x2].p[swi]=y3; lists[x1].p[swi]=y2;lists[x3].p[!swi]=y2; lists[y1].p[swi]=x2;lists[y3].p[!swi]=x2; lists[y2].p[!swi]=x1;lists[y2].p[swi]=x3; check(x2);check(y2); } void reverses() { swap(head,tail); swi=!swi; swap(lm,rm); } LL cacu() { int g=0; LL ans=0; for(int i=head;g<n&&i>=1&&i<=n;i=lists[i].p[swi]) { g++; if(g%2) { ans+=i; } } return ans; } void open() { freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); } int main() { // open(); int T=0; while(~scanf("%d%d",&n,&m)) { swi=1; int x; memset(lists,0,sizeof(lists)); for(int i=1; i<=n; i++) { lists[i].data=i; lists[i].p[!swi]=i-1; lists[i].p[swi]=i+1; } head=1;tail=n;lm=0;rm=n+1; int op,y; for(int i=1; i<=m; i++) { op=Scan(); if(op!=4) { x=Scan();y=Scan(); if(x<1||x>n||y<1||y>n) continue; if(x==y) continue; } switch(op) { case 1: movesl(y,x); break; case 2: movesr(y,x); break; case 3: swaps(x,y); break; case 4: reverses();break; } } LL ans=0,ans1; ans=cacu(); printf("Case %d: %lld ",++T,ans); } return 0; }