UVA 12657 Boxes in a Line
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
题意:给你一个初始数组a[i]=i,每次有四种操作,第一种操作把x移到y前面,第二种操作把x移到y后面,第三种操作把x和y交换位置,第四种操作翻转整个序列。
思路:此题的关键就是第四种操作怎么进行,其实翻转之后操作一变为把x移到y后面,操作二变为把x移到y前面,操作三不变。
此题仍有一点需要注意的是要判断交换的时候还需要判断x和y是否是相邻的。
#include <map> #include <set> #include <stack> #include <queue> #include <cmath> #include <ctime> #include <vector> #include <cstdio> #include <cctype> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #include<bitset> using namespace std; #define INF 0x3f3f3f3f #define inf -0x3f3f3f3f #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define mem0(a) memset(a,0,sizeof(a)) #define mem1(a) memset(a,-1,sizeof(a)) #define mem(a, b) memset(a, b, sizeof(a)) const int maxn=100100; int l[maxn],r[maxn]; void link(int a,int b){ r[a]=b,l[b]=a; } int main(){ int n,m,cas=0; while(scanf("%d%d",&n,&m)!=EOF){ int flag=0; int x,y,op; for(int i=1;i<=n;i++) r[i]=i+1,l[i]=i-1; r[0]=1,l[0]=-1;r[n+1]=-1,l[n+1]=n; for(int i=1;i<=m;i++){ scanf("%d",&op); if(op==4){ flag^=1; continue; } if(flag&&op<=2) op=3-op; scanf("%d%d",&x,&y); 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) //将x插入到y的前面 link(lx,rx),link(ly,x),link(x,y); else if(op==2) //将x插入到y的后面 link(lx,rx),link(y,x),link(x,ry); else{ if(rx==y) link(lx,rx),link(y,x),link(x,ry); else if(l[x]==y) link(lx,rx),link(ly,x),link(x,y); else link(lx,y),link(y,rx),link(ly,x),link(x,ry); } } int k=0; long long ans=0; for(int i=1;i<=n;i++){ k=r[k]; if(i&1) ans+=k; } if(flag) ans=(long long)n*(n+1)/2-ans; printf("Case %d: %lld\n",++cas,ans); } return 0; }