本题由于用普通数组时间耗费太大,又考虑到左右关系,使用双向链表;
使用双向链表转移时 需注意: 移动合法;
link(x,y); x和y不能为其本身(1个元素的双向链表);
交换两元素分为两种情况,两者相邻和不相邻,
做任何移动之前,要看链表本身是否已符合链表移动后的要求;
#include <map> #include <vector> #include <cstdio> #include <cstring> #include <iostream> #define INF 10000000 //using namespace std; typedef long long LL; const int maxn = 100100; int a[maxn],left[maxn],right[maxn],head; void link(int x,int y){ right[x]=y; left[y]=x; } int n,m; int main() { int kase=1; while(scanf("%d %d",&n,&m)==2){ for(int i=1;i<=n-1;i++){ left[i]=i-1; right[i]=i+1; } left[0]=n; right[0]=1; left[n]=n-1; right[n]=0; // int tt=0; // for(int i=0;i<n*3;i++){ // printf("%d ",tt); tt=right[tt]; // } // printf("\n"); int order,fff=0,x,y; for(int i=0;i<m;i++){ scanf("%d",&order); if(order==4) {fff=!fff; continue;} scanf("%d %d",&x,&y); if(order!=3&&fff) order=3-order; if(order==3&&right[y]==x) std::swap(x,y); int lx=left[x],rx=right[x],ly=left[y],ry=right[y]; if(order==1){ if(left[y]==x) continue; link(lx,rx); link(ly,x); link(x,y); } else if(order==2){ if(right[y]==x) continue; link(lx,rx); link(y,x); link(x,ry); } else{ 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); } } } LL sum=0,All=(LL)(1+n)*n/2; int st=0; for(int i=1;i<=n;i++){ st=right[st]; if(i&1) sum+=st; //std::cout<<st<<" "; } //std::cout<<"\n"; if(n%2==0&&fff) sum=All-sum; std::cout<<"Case "<<kase++<<": "<<sum<<std::endl; } return 0; }