这道题要考虑一些细节。
当要交换位置的时候,X与Y相邻需要特殊处理。
#include<iostream> #include<cstdio> #include<cstring> #define MAXN 100200 using namespace std; long long Right[MAXN], Lift[MAXN]; void link(int X, int Y) { Right[X] = Y; Lift[Y] = X; } int main() { #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); #endif // ONLINE_JUDGE int n, m, Case = 0; while(cin >> n >> m) { memset(Lift, 0, sizeof(Lift)); memset(Right, 0, sizeof(Right)); bool inx = false; long long sum = 0, cur = 0; for(int i = 1; i <= n; i++) { link(i, i + 1); link(i - 1, i); } while(m--) { int cmd, X, Y; cin >> cmd; if(cmd == 4) { inx = !inx; continue; } cin >> X >> Y; if(cmd == 3&&(Right[Y] == X)) swap(X, Y); if(cmd != 3&& inx) cmd = 3 - cmd; if(cmd == 1&& Lift[Y] == X) continue; if(cmd == 2&& Right[Y] == X) continue; int XL = Lift[X], XR = Right[X], YL = Lift[Y], YR = Right[Y]; if(cmd == 3) { if(Right[X] == Y) { link(XL, Y); link(Y, X); link(X, YR); } else { link(X, YR); link(YL, X); link(Y, XR); link(XL, Y); } } else if(cmd == 2) { link(Y, X); link(X, YR); link(XL, XR); } else if(cmd == 1) { link(XL, XR); link(YL, X); link(X, Y); } } for(int i = 1; i <= n; i++) { cur = Right[cur]; if(i & 1) sum += cur; } if(inx&& !(n & 1)) sum = (long long)n / 2 * (n + 1) - sum; printf("Case %d: %lld\n", ++Case, sum); } return 0; }