题意就是给你1~n,n个数按顺序排好,然后4个操作,
t=1时,把x放到y左边;
t=2时,把x放到y右边;
t=3时,把x跟y换一下;
t=4时,整个数列倒序;
最后问从第一个数开始奇数位置的数之和
如果用链表,1,2,3,都容易实现,但是t=4时用链表怎么搞呢。。。
不用怕。。。倒序就相当于左右变换一下嘛,
那么,就容易解决啦~
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define LL long long
using namespace std;
int a[2][200000];//a[0][x]表示x左边的数,a[1][x]表示x右边的数
int n,m;
void init()
{
a[0][n+1]=n;
for(int i=0;i<=n;i++)
{
a[0][i]=i-1;
a[1][i]=i+1;
}
}
void swapa(int x,int y)
{
if(a[1][x]==y)
{
int xl,yr;
xl=a[0][x];
yr=a[1][y];
a[1][xl]=y;
a[0][y]=xl;
a[1][y]=x;
a[0][x]=y;
a[1][x]=yr;
a[0][yr]=x;
return;
}
if(a[0][x]==y)
{
int xr,yl;
xr=a[1][x];
yl=a[0][y];
a[1][yl]=x;
a[0][x]=yl;
a[1][x]=y;
a[0][y]=x;
a[1][y]=xr;
a[0][xr]=y;
return;
}
int xr,xl,yr,yl;
xr=a[1][x];
xl=a[0][x];
yr=a[1][y];
yl=a[0][y];
a[0][x]=yl;
a[1][x]=yr;
a[0][yr]=x;
a[1][yl]=x;
a[0][y]=xl;
a[1][y]=xr;
a[0][xr]=y;
a[1][xl]=y;
}
void turn(int x,int y,int p)
{
if(a[p][y]==x) return;
int xr,xl,yp;
xr=a[1][x];
xl=a[0][x];
yp=a[p][y];
a[0][xr]=xl;
a[1][xl]=xr;
a[1-p][yp]=x;
a[p][y]=x;
a[1-p][x]=y;
a[p][x]=yp;
}
int main()
{
//freopen("1.in","r",stdin);
int cas=1;
while(scanf("%d %d",&n,&m)==2)
{
int t,p=0;
int x,y;
init();
while(m--)
{
scanf("%d",&t);
if(t==4) p=1-p;
else
{
scanf("%d %d",&x,&y);
if(t==1) turn(x,y,p);
if(t==2) turn(x,y,1-p);
if(t==3) swapa(x,y);
}
}
if((n&1)) p=0;
x=a[1][0];
if(p) x=a[0][n+1];
t=1;
LL ans=0;
while(t<=n)
while(x>0 && x<=n)
{
//printf("x=%d,t=%d\n",x,t);
if(t&1) ans+=(LL)x;
t++;
x=a[1-p][x];
}
printf("Case %d: %lld\n",cas++,ans);
}
return 0;
}