点击打开题目链接
数组实现双向链表模拟操作。
lrj代码技巧是采用了一个标记变量,避免了操作4对所有元素指针的修改,并能统一其他操作。
swap用来处理当op=3时l[x]=y的情况,和后面l[y]=x统一。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 100000 + 5;
int l[maxn], r[maxn];
int n, m;
int op, x, y;
void link(int x, int y) {
r[x] = y;
l[y] = x;
}
int main() {
//ios::sync_with_stdio(false);
int kase = 0;
while(cin >> n >> m) {
for(int i = 1; i <= n; i++) {
l[i] = i - 1;
r[i] = (i + 1) % (n + 1);
}
l[0] = n;
r[0] = 1;
int flag = 0;
while(m--) {
cin >> op;
if(op == 4) flag = !flag;
else {
cin >> x >> y;
if(op == 3 && r[y] == x) swap(x, y); //方便统一后面op为3时x和y相邻的操作
if(op != 3 && flag) op = 3 - op;
if(op == 1 && l[y] == x) continue;
if(op == 2 && r[y] == x) continue;
int lx = l[x], rx = r[x], ly = l[y], ry = r[y];
if(op == 1) {
link(lx, rx);
link(ly,x);
link(x, y);
}
if(op == 2) {
link(lx, rx);
link(x, ry);
link(y, x);
}
if(op == 3) {
if(r[x] == y)
link(lx, y), link(y, x), link(x, ry);
else
link(lx, y), link(y, rx), link(ly, x), link(x, ry);
}
}
}
ll ans = 0;
int k = 0;
for(int i = 1; i <= n; i++) {
k = r[k];
if(i & 1) ans += k;
}
if(flag && n % 2 == 0) ans = (ll)n / 2 * (n + 1) - ans;
printf("Case %d: %lld\n",++kase,ans);
}
return 0;
}