UVA12657 移动盒子 链表

来源:互联网 发布:芮纳纪 淘宝 编辑:程序博客网 时间:2024/05/17 22:53

You have n boxes in a line on the table numbered 1 … n from left to right. Your task is to simulate 4
kinds of commands:
• 1 X Y : move box X to the left to Y (ignore this if X is already the left of Y )
• 2 X Y : move box X to the right to Y (ignore this if X is already the right of Y )
• 3 X Y : swap box X and Y
• 4: reverse the whole line.
Commands are guaranteed to be valid, i.e. X will be not equal to Y .
For example, if n = 6, after executing 1 1 4, the line becomes 2 3 1 4 5 6. Then after executing
2 3 5, the line becomes 2 1 4 5 3 6. Then after executing 3 1 6, the line becomes 2 6 4 5 3 1.
Then after executing 4, then line becomes 1 3 5 4 6 2
Input
There will be at most 10 test cases. Each test case begins with a line containing 2 integers n, m
(1 ≤ n, m ≤ 100, 000). Each of the following m lines contain a command.
Output
For each test case, print the sum of numbers at odd-indexed positions. Positions are numbered 1 to n
from left to right.
Sample Input
6 4
1 1 4
2 3 5
3 1 6
4
6 3
1 1 4
2 3 5
3 1 6
100000 1
4
Sample Output
Case 1: 12
Case 2: 9
Case 3: 2500050000

#include<bits/stdc++.h>const int INF  = 0x3f3f3f3f;const int Maxn = 100005;#define MST(s,q) memset(s,q,sizeof(s))#define Lchild id<<1#define Rchild (id<<1)+1using namespace std;int n, m, Right[Maxn], Left[Maxn];void Link(int A, int B) {  // 连接A,B    Right[A] = B, Left[B] = A;}int main() {    int icase = 1;    while (cin >> n >> m) {        for (int i = 0; i <= n; i++)            Right[i] = i + 1, Left[i] = i - 1;        Left[0] = 0;        int Reverse = 0, a, b, x;        for (int i = 1; i <= m; i++) {            scanf("%d", &x);            if (x == 4) {  // 反转                Reverse = 1 - Reverse;            } else {                scanf("%d%d", &a, &b);                int La = Left[a], Lb = Left[b], Ra = Right[a], Rb = Right[b];                if (x == 3) { // 交换a,b                    if (Right[a] == b) {                        Link(La, b);Link(b, a); Link(a, Rb);                    } else if (Right[b] == a) {                        Link(Lb, a); Link(a, b);Link(b, Ra);                    } else {                        Link(La, b); Link(b, Ra); Link(Lb, a);Link(a, Rb);                    }                }                else {                    if (Reverse) x = 3 - x;                    if (x == 1) { // 把a移到b左边                        if (Left[b] == a) continue;                        Link(La, Ra);Link(Lb, a); Link(a, b);                    } else if (x == 2) { // 把a移到b右边                        if (Right[b] == a)continue;                        Link(La, Ra);Link(b, a);Link(a, Rb);                    }                }            }//            for (int i = Right[0]; i != n + 1; i = Right[i])//                cout << i;//            cout << endl;        }        long long ans = 0, k = 1;        for (int i = Right[0]; i != n + 1; i = Right[i]) {            if (k++ % 2 == 1) ans += i;        }        k--; // 循环结束时k=n+1;        if (Reverse) ans = ((k * (k + 1)) / 2) - ans;        printf("Case %d: %lld\n", icase++, ans);    }}
0 0
原创粉丝点击