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
好麻烦的链表,写swl。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
int nex[100005],las[100005];
void link(int x,int y)//x插入y左边
{
nex[x] = y;las[y] = x;
}
int main()
{
int n,m;
int kase = 0;
while(~scanf("%d%d",&n,&m))
{
for(int i = 1;i < n;i++)
{
nex[i] = i + 1;
las[i] = i - 1;
}
nex[n] = 0;las[n] = n - 1;nex[0] = 1;las[0] = n;
ll ans = 0;
int is_reverse = 0;
for(int i = 1;i <= m;i++)
{
int op;scanf("%d",&op);
if(op == 4)
{
is_reverse ^= 1;
continue;
}
if(is_reverse && op <= 2)
{
op = 3 - op;
}
int x,y;scanf("%d%d",&x,&y);
int lx = las[x],rx = nex[x],ly = las[y],ry = nex[y];
if(op == 1)
{
if(ly == x)continue;
link(lx,rx);link(ly,x);link(x,y);
}
else if(op == 2)
{
if(ry == x)continue;
link(lx,rx);link(y,x);link(x,ry);
}
else if(op == 3)
{
if(rx == y)
{
link(lx,y);link(y,x);link(x,ry);
}
else if(lx == y)
{
link(ly,x);link(x,y);link(y,rx);
}
else
{
link(ly,x);link(x,ry);link(lx,y);link(y,rx);
}
}
}
ll sum = 1ll * (1 + n) * n / 2;
ll ans1 = 0;
int cnt = 0;
for(int i = nex[0];i;i = nex[i])
{
cnt++;
if(cnt % 2 == 1)ans1 += i;
}
printf("Case %d: ",++kase);
if(is_reverse && n % 2 == 0)
{
printf("%lld\n",sum - ans1);
}
else
{
printf("%lld\n",ans1);
}
}
return 0;
}
//10 1
//2 1 10
//27 6
//1 7 18
//4
//1 19 4
//1 5 19
//1 15 11
//4