题目链接:http://codeforces.com/problemset/problem/669/D
Little Artem is fond of dancing. Most of all dances Artem likes rueda — Cuban dance that is danced by pairs of boys and girls forming a circle and dancing together.
More detailed, there are n pairs of boys and girls standing in a circle. Initially, boy number 1 dances with a girl number 1, boy number 2dances with a girl number 2 and so on. Girls are numbered in the clockwise order. During the dance different moves are announced and all pairs perform this moves. While performing moves boys move along the circle, while girls always stay at their initial position. For the purpose of this problem we consider two different types of moves:
- Value x and some direction are announced, and all boys move x positions in the corresponding direction.
- Boys dancing with even-indexed girls swap positions with boys who are dancing with odd-indexed girls. That is the one who was dancing with the girl 1 swaps with the one who was dancing with the girl number 2, while the one who was dancing with girl number 3 swaps with the one who was dancing with the girl number 4 and so one. It's guaranteed that n is even.
Your task is to determine the final position of each boy.
The first line of the input contains two integers n and q (2 ≤ n ≤ 1 000 000, 1 ≤ q ≤ 2 000 000) — the number of couples in the rueda and the number of commands to perform, respectively. It's guaranteed that n is even.
Next q lines contain the descriptions of the commands. Each command has type as the integer 1 or 2 first. Command of the first type is given as x ( - n ≤ x ≤ n), where 0 ≤ x ≤ n means all boys moves x girls in clockwise direction, while - x means all boys move x positions in counter-clockwise direction. There is no other input for commands of the second type.
Output n integers, the i-th of them should be equal to the index of boy the i-th girl is dancing with after performing all q moves.
6 3
1 2
2
1 2
4 3 6 5 2 1
2 3
1 1
2
1 -2
1 2
4 2
2
1 3
思路:开始我是这样想的记录前进的步数和交换的次数,在最后统一处理,但是最后发现想第三数据就不行,因为先前进后换和先换后先进是不一样
的。
比如
4 2
2
1 3 的答案是1 4 2 3
而
4 2
1 3
2 的答案是3 2 1 4
最后才知道,按奇偶分开移动。因为我们可以知道这样几个的性质:
1.奇数与奇数的位置一定是相隔2个,偶数与偶数得到的位置一定是相隔2个。因为不管是变化1前进几步都是相隔2个,变化2交换的时候是2个2个交换的
所以他们的状态没变还是相隔2个。
2.在奇数位置的男生变化2交换位置相当于前进了一个位置,而偶数位置的男生相当于后退了一步。所以我们只要把两种变化都看作前进,计算前进的步数,
最后在奇数的前进排下,偶数的前进排下。
代码:
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> using namespace std; const int maxn=1e6+10; int ans[maxn]; int main() { int n,m,x,y,sum1=0,sum2=0;//sum1记录奇数男生的前进步数,sum2是偶数男生的 scanf("%d%d",&n,&m); while(m--) { scanf("%d",&x); if(x==1) { scanf("%d",&y); sum1+=y; sum2+=y; } else if(x==2) { if(sum1%2==1)//奇数男生走奇数步到达偶数位置,所以步数相当于减一 sum1--; else sum1++; if(sum2%2==1)//偶数男生走奇数步到达偶数位置,步数相当于加一 sum2++; else sum2--; } while(sum1<0)//防止负数 sum1+=n; sum1%=n;//只取余数就可以了,前进n的倍数还是原来的位置 while(sum2<0) sum2+=n; sum2%=n; } for(int i=1;i<=n;i+=2) { if(i+sum1==n)//特判正好移到n的位置 ans[n]=i; else ans[(i+sum1)%n]=i; if(i+1+sum2==n) ans[n]=i+1; else ans[(i+1+sum2)%n]=i+1; } for(int i=1;i<=n;i++) { if(i!=n) printf("%d ",ans[i]); else printf("%d ",ans[i]); } return 0; }