题目链接:
Codeforces #669 Div2. D. Little Artem and Dance
题意:
初始有n对男生和女生,编号都是从1–n,并且1号男生和1号女生配对,2号男生和2号女生配对…n号男生和n号女生配对。这些配对的男女生初始顺时针编号从小到大围成一圈。
有两种操作,均是只移动男生:
1 x 将所有男生都顺时针移动x位(x<0时是逆时针移动|x|位),例如x=2时,在3号位的男生就移到了5号位。
2 将所有两两相邻的男生换位,即1号位男生和2号位男生换位,3号位男生和4号位男生换位等。问Q次操作后,从1到n输出所有女生匹配的男生编号。
数据范围n<=1e6,Q<=2e6
分析;
注意到所有奇数编号和偶数编号的男生的相对顺序都不变,基于这一点,只需要记录编号为1和2男生的位置
那么剩下所有男生的位置都可以递推出来了。
假设1号和2号男生的位置分别是one和two。
对于操作1很简单:one和two直接加上x,然后对n取模,考虑负数和0的情况。
对于操作2,因为是奇数偶数和相邻偶数位置交换且one的奇偶性和two不同,所以需要判断one的奇偶。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <climits>
#include <cmath>
#include <ctime>
#include <cassert>
#define IOS ios_base::sync_with_stdio(0); cin.tie(0)
using namespace std;
const int MAX_N=1000010;int n,Q,one,two;
int ans[MAX_N];inline int change(int x,int d)
{int res=((x+d)%n+n)%n;if(res==0) res=n;return res;
}int main()
{freopen("Din.txt","r",stdin);while(~scanf("%d%d",&n,&Q)){one=1,two=2;for(int i=0;i<Q;i++){int t;scanf("%d",&t);if(t==2){if(one&1){one=change(one,1);two=change(two,-1);}else {one=change(one,-1);two=change(two,1);}}else {int a;scanf("%d",&a);one=change(one,a);two=change(two,a);}}for(int i=1;i<=n-1;i+=2){//printf("one=%d i=%d\n",one,i);ans[one]=i;one=change(one,2);}for(int j=2;j<=n;j+=2){//printf("two=%d j=%d\n",two,j);ans[two]=j;two=change(two,2);}for(int i=1;i<=n;i++){printf("%d ",ans[i]);}printf("\n");}return 0;
}