较为复杂的一题;有点类似6-1 但是分析完之后比6-1简单 就是按照思路模拟就好!
学会了双向链表 先初始化 link是关键
分析命令 可以大大简化代码 :
反转链表不用反转 改操作和输出就行;
#include<bits/stdc++.h> using namespace std; void link(int ,int); int left1[100005],right1[100005]; int main() { int n,Q;int cas=1; while(cin>>n>>Q){ int flag=0; memset(left1,0,sizeof(left1)); memset(right1,0,sizeof(right1)); for(int i=1;i<=n;i++) { left1[i]=i-1; right1[i]=(i+1)%(n+1); } left1[0]=n;right1[0]=1; while(Q--) { int q;cin>>q; if(q==4){flag=!flag; continue;} int X,Y;cin>>X>>Y; if(q==3){if(right1[Y]==X)swap(X,Y);} if(q!=3&&flag)q=3-q; if(q==1)if(right1[X]==Y)continue; if(q==2)if(right1[Y]==X)continue; int XL=left1[X],XR=right1[X],YL=left1[Y],YR=right1[Y]; if(q==1) { link(XL,XR);link(YL,X);link(X,Y); } if(q==2) { link(XL,XR);link(Y,X);link(X,YR); } if(q==3) { if(right1[X]==Y) { link(Y,X);link(XL,Y);link(X,YR); } else { link(XL,Y);link(Y,XR); link(YL,X);link(X,YR); } } } long long sum=0; int b=0; for(int i=1;i<=n;i++) { b=right1[b]; if(i%2==1)sum+=b; } if(flag&&n%2==0)sum=(long long)n*(n+1)/2-sum; printf("Case %d: %lld\n",cas++,sum); } return 0; } void link(int l,int r) { right1[l]=r;left1[r]=l; }
注意细节!分析所有情况!
此外 第三个命令时一定要注意是否相邻!