题目意思是说,给出一个数n,表示存在一个整数序列1……n,然后进行四种操作:
操作一:输入x,y,表示将x移到y的左边(若x本来就在y的左边则忽略);
操作二:输入x,y,表示将x移到y的右边(若x本来就在y的右边则忽略);
操作三:输入x,y,表示交换x和y。
操作四:将整个序列倒置。
最后要求的是操作后的整个序列奇数项的和。
6 4
1 1 4
2 3 5
3 1 6
4
6 3
1 1 4
2 3 5
3 1 6
100000 1
4
Sample Output
Case 1: 12
Case 2: 9
Case 3: 2500050000
#include <iostream>
#include <algorithm>
using namespace std;
const int MAX_N=1000;
int lleft[MAX_N],rright[MAX_N];
void link(int L,int R) //把L和R进行连接 必须L在前R在后
{
rright[L]=R;lleft[R]=L;
}
int main()
{
int n,m,x,y,op;
while(cin>>n>>m)
{
for(int i=1;i<=n;i++)
{
lleft[i]=i-1;
rright[i]=(i+1)%(n+1);
}
lleft[0]=n;rright[0]=1;
int inv=0;
for(int i=1;i<=m;i++)
{
cin>>op;
if(op==4) inv=!inv; //反转记录
else
{
cin>>x>>y;
if(op==3 && rright[y]==x) swap(x,y); //如果a在b的右边
if(op!=3 && inv) op=3-op; //如果是在反转后操作
if(op==1 && x==lleft[y]) continue;//如果x本身就在y的左边
if(op==2 && x==rright[y]) continue; //如果x本身就在y的右边
int lx=lleft[x],rx=rright[x],ly=lleft[y],ry=rright[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(rright[x]==y)
{
link(lx,y);link(y,x);link(x,ry);
}
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=rright[b];
cout << b << endl;
if(i%2==1) ans+=b;
}
if(inv && n%2==0) ans=(long long)n*(n+1)/2-ans;
cout << ans << endl;
}
}
return 0;
}