题意:n个盒子从1~n编号,从左到右排好,现在有m条命令,包含下面4种
1 x y :代表将x移到y的左边
2 x y :代表将x移到y的右边
3 x y :代表将两个盒子的位置交换
4 :代表将反转所有盒子,最后一个到第一个,第一个到最后一个,一次类推
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 100001;
int left[maxn],right[maxn];
void link(int a,int b)
{
right[a]=b;
left[b]=a;
}
int main()
{
int n,m,cmd,r,x,y,kcase=0;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=1;i<=n;i++)
{
right[i]=(i+1)%(n+1);
left[i]=i-1;
}
r=0;
right[0]=1;left[0]=n;
while(m--)
{
scanf("%d",&cmd);
if(cmd==4)
{
r=!r;
continue;
}
scanf("%d%d",&x,&y);
/* if(cmd==1&&r)cmd=3-cmd;
if(cmd==2&&r)cmd=3-cmd;//又犯这种错误
*/
if(cmd!=3&&r)cmd=3-cmd;
if(cmd==3&&right[y]==x)swap(x,y);
if((cmd==1&&left[y]==x))continue;
if((cmd==2&&right[y]==x))continue;
int lx,rx,ly,ry;
lx = left[x];rx = right[x];ly = left[y];ry = right[y];
if(cmd==1)
{
link(ly,x);link(x,y);link(lx,rx);
}
if(cmd==2)
{
link(x,ry);link(y,x);link(lx,rx);
}
if(cmd==3)
{
if(right[x]==y)// x y
{
link(x,ry);link(y,x);link(lx,y);
}
else
{
link(ly,x);link(x,ry);
link(lx,y);link(y,rx);
}
}
}
long long b = 0;
long long ans=0;
for(int i=1;i<=n;i++)
{
b=right[b];
if(i%2==1)ans+=b;
}
long long temp = (long long)n*(n+1)/2;
if(n%2==0&&r==1)ans = temp-ans;
printf("Case %d: %lld\n",++kcase,ans);
}
}