例题6-5 移动盒子(Boxes in a Line, UVa 12657)

来源:互联网 发布:韩国进出口数据 编辑:程序博客网 时间:2024/06/07 12:17
这题emmm,感觉还是没有深刻理解。
1. 对于逆转操作采取加标记而非直接改动。
2. 操作前先记下节点的前驱与后继。
#include <iostream>#include <string>#include <vector>#include <stack>#include <queue>#include <deque>#include <set>#include <map>#include <algorithm>#include <functional>#include <utility>#include <cstring>#include <cstdio>#include <cstdlib>#include <ctime>#include <cmath>#include <cctype>#define CLEAR(a, b) memset(a, b, sizeof(a))#define IN() freopen("in.txt", "r", stdin)#define OUT() freopen("out.txt", "w", stdout)#define LL long long#define maxn 100005#define maxm 6000005#define mod  10007#define INF 1000000007#define EPS 1e-7#define PI 3.1415926535898#define N 4294967296using namespace std;//-------------------------CHC------------------------------//int L[maxn], R[maxn];void link(int x, int y) { R[x] = y, L[y] = x; }void init(int n) {R[0] = 1;for (int i = 1; i <= n; ++i) L[i] = i - 1, R[i] = i + 1;}void debug(int n) {int p = 0;while (n--) {p = R[p];printf("%d ", p);}puts("");}int main() {//IN(); OUT();int n, m, kase = 1;while (~scanf("%d%d", &n, &m)) {init(n);int op, x, y;bool rev = false;while (m--) {scanf("%d", &op);if (op == 4) rev = !rev;else {scanf("%d%d", &x, &y);if (op == 3 && R[y] == x) swap(x, y);if (op != 3 && rev) op = 3 - op;int Lx = L[x], Rx = R[x], Ly = L[y], Ry = R[y];//预先保存if (op == 1) {if (Rx == y) continue;else link(Lx, Rx), link(Ly, x), link(x, y);}else if (op == 2) {if (Lx == y) continue;else link(Lx, Rx), link(y, x), link(x, Ry);}else {if (Rx == y) link(Lx, y), link(y, x), link(x, Ry);else link(Lx, y), link(y, Rx), link(Ly, x), link(x, Ry);}}//debug(n);}LL ans = 0;int p = 0;for (int i = 1; i <= n; ++i) {p = R[p];if (i & 1) ans += p;}if (rev && n % 2 == 0) ans = (LL)n * (n + 1) /2 - ans;printf("Case %d: %lld\n", kase++, ans);}return 0;}

原创粉丝点击