说一下题意:
给你一个长度为n,节点值由1到n的链表。
定义四种操作:
1 X Y:把值为X的节点放到值为Y 的节点左边。
2 X Y:把值为Y的节点放到值为X的节点右边。
3 X Y:交换X、Y两个节点
4:翻转整个链表
说一下坑点:
1.初始化链表时用循环写。递归会导致栈溢出。
2.注意细节,首节点和尾节点注意一下。
3.翻转后,其实可以看做还是原来的链表,只是1、2操作功能对调
4.你可以不翻转链表,坑点3提示的操作,最后计算奇数节点值的时候判断一下是从左向右还是反方向就行。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e5+5;
struct node
{
int val;
node *lp,*rp;
}oo[N];
node *pp[N];
node* leftt,*rightt;
///初始化链表
void mark_list(int n)
{
int i=1;
while(i<=n)
{
pp[i]=&oo[i];
oo[i].val=i;
oo[i].lp=&oo[i-1];
oo[i].rp=&oo[i+1];
i++;
}
oo[1].lp=NULL;
oo[n].rp=NULL;
leftt=pp[1];
rightt=pp[n];
}
void remove_a(node*a)
{
if(a->lp==NULL)
{
(a->rp)->lp=NULL;
leftt=a->rp;
}
else if(a->rp==NULL)
{
(a->lp)->rp=NULL;
rightt=a->lp;
}
else
{
(a->lp)->rp=a->rp;
(a->rp)->lp=a->lp;
}
}
void toleft(node* a,node* b)
{
remove_a(a);
if(b->lp!=NULL)
{
(b->lp)->rp=a;
a->lp=(b->lp);
}
else
{
a->lp=NULL;
}
b->lp=a;
a->rp=b;
if(leftt==b) leftt=a;
}
void toright(node* a,node* b)
{
remove_a(a);
if(b->rp!=NULL)
{
(b->rp)->lp=a;
a->rp=(b->rp);
}
else
{
a->rp=NULL;
}
b->rp=a;
a->lp=b;
if(rightt==b) rightt=a;
}
void just_swap(node *a,node *b)
{
int t;
t=a->val;
a->val=b->val;
b->val=t;
pp[a->val]=a;
pp[b->val]=b;
}
ll sum(bool flag)
{
ll ans=0;
bool mark=true;
node *p=(flag ? rightt:leftt);
while(p!=NULL)
{
if(mark)
{
ans+=p->val;
}
p=(flag ? p->lp:p->rp);
mark=!mark;
}
return ans;
}
void putlink()
{
node *p=leftt;
while(p!=NULL)
{
cout<<(p->val)<<" ";
p=p->rp;
}
cout<<""<<endl;
}
int main()
{
int n,m,Case=0;
while(cin>>n>>m)
{
mark_list(n);
bool mark;
mark=false;
while(m--)
{
int op,x,y;
cin>>op;
if(mark)
{
if(op==1) op=2;
else if(op==2) op=1;
}
switch(op)
{
case 1:
cin>>x>>y;
if(pp[y]->lp!=pp[x]&&n!=1)
{
toleft(pp[x],pp[y]);
}
//putlink();
break;
case 2:
cin>>x>>y;
if(pp[y]->rp!=pp[x]&&n!=1)
{
toright(pp[x],pp[y]);
}
//putlink();
break;
case 3:
int x,y;
cin>>x>>y;
if(n!=1)
{
just_swap(pp[x],pp[y]);
}
//putlink();
break;
case 4:
mark=!mark;
//putlink();
break;
default:
break;
}
}
cout<<"Case "<<(++Case)<<": "<<sum(mark)<<endl;
}
return 0;
}