双向链表的两端各放一个0。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
const int MAXN=100000+10;
int left[MAXN],right[MAXN];
void Link(int L,int R)
{
right[L]=R;left[R]=L;
}
int main()
{
int n,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);
}
left[0]=n;right[0]=1;
int op,X=0,Y=0,inv=0;
while(m--)
{
scanf("%d",&op);
if(op==4) inv=!inv;
else{
scanf("%d%d",&X,&Y);
if(op!=3&&inv) op=3-op;
if(op==1&&left[Y]==X) 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(LY,X);Link(X,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 if(right[Y]==X) {Link(LY,X);Link(X,Y);Link(Y,RX);}
else {Link(LX,Y);Link(Y,RX);Link(LY,X);Link(X,RY);}
}
}
}
int b=0;
long long ans=0;
for(int i=1;i<=n;i++)
{
b=right[b];
if(i%2==1) ans+=b;
}
if(n%2==0&&inv) ans=(long long)n*(1+n)/2-ans;
printf("Case %d: %lld\n",++kase,ans);
}
return 0;
}