Codeforces #669 Div2. D. Little Artem and Dance(思维)

题目链接:
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 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#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;iint 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;
}

你可能感兴趣的:(Codeforces)