这里写的并不是uva上的那个题,而是upc上的一个题,所以,稍微有些不同
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:
(i) 1 X Y: move box X to the left to Y (ignore this if X is already the left of Y)
(ii) 2 X Y: move box X to the right to Y (ignore this if X is already the right of Y)
(iii) 3 X Y: swap box X and Y
(iv) 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.输入
The input contains several test cases and is terminated by End-Of-File (EOF). Each test case begins with a line containing 2 integers n, m. Each of the following m lines contain a command.
输出
For each test case, print the sum of numbers at odd-indexed positions. Positions are numbered 1 to n from left to right.
样例输入
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样例输出
12 9 2500050000
题意:
给你一个n,表示长度为n的序列{1,2,3,4,5...n}
4个操作:
1,x,y,把x移动到y左边
2,x,y,把x移动到y右边
3,x,y,把x,y互换
4,翻转整个数组
题解:
模拟双向链表
记录每个数左边出现的是谁,右边出现的是谁,这样每次操作就可以O1了
对于操作4,打一个标记即可,打完标记后,1,2操作就反向了,即原本1操作要换成2操作
值得注意的一点是,如果要操作的两个数紧挨着(或者说相邻),那么要特殊处理,否者指针就乱了
最后结果不是t,就是wa
/*author:revolIA*/
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const int maxn = 1e6+7;
int n,m,l[maxn],r[maxn];
void debug(){
for(int i=0;r[i]<=n;i=r[i])printf("%d ",r[i]);
puts("");
for(int i=n+1;l[i];i=l[i])printf("%d ",l[i]);
puts("");
}
void connect(int x,int y){l[y] = x,r[x] = y;}
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
r[0] = 1;
l[0] = 0;
for(int i=1;i<=n+1;i++)l[i] = i-1,r[i] = i+1;
int flag = 0,opt,x,y;
while(m--){
scanf("%d",&opt);
if(opt == 4){
flag ^= 1;
}else{
scanf("%d%d",&x,&y);
int lx = l[x],rx = r[x];
int ly = l[y],ry = r[y];
if(opt == 3){
if(l[x] == y){
connect(ly,x);
connect(x,y);
connect(y,rx);
}else if(l[y] == x){
connect(lx,y);
connect(y,x);
connect(x,ry);
}else{
connect(lx,y);
connect(y,rx);
connect(ly,x);
connect(x,ry);
}
}else{
if(flag)opt = 3-opt;
if(opt == 1){
if(l[y] == x)continue;
if(l[x] == y){
connect(ly,x);
connect(x,y);
connect(y,rx);
}else{
connect(lx,rx);
connect(ly,x);
connect(x,y);
}
}else{
if(r[y] == x)continue;
if(r[x] == y){
connect(x,ry);
connect(y,x);
connect(lx,y);
}else{
connect(lx,rx);
connect(y,x);
connect(x,ry);
}
}
}
}
}
//debug();
ll ans = 0;
for(int i=0;r[i]<=n;i = r[r[i]])ans += r[i];
if(n%2 == 0 && flag)ans = (1LL+n)*n/2-ans;
printf("%lld\n",ans);
}
return 0;
}