Codeforces 669D Little Artem and Dance【思维】好题!好题!

D. Little Artem and Dance
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

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 2 dances 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:

  1. Value x and some direction are announced, and all boys move x positions in the corresponding direction.
  2. 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.

Input

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

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.

Examples
Input
6 3
1 2
2
1 2
Output
4 3 6 5 2 1
Input
2 3
1 1
2
1 -2
Output
1 2
Input
4 2
2
1 3
Output
1 4 3 2

题目大意:

一共有N对男女在跳舞,站成一个圈,一开始i号男生和i号女生在一起跳,过程中有Q次改变位子的操作,女孩一直不动,男生会动。

1 x:表示所有男生要移动X个位子,对应X>0是顺时针,否者就是逆时针。

2:表示位子【x,x+1】的男生交换位子 (x从1开始,X包括:【1,3,5,7.............】)。

问最终每个位子上都是什么编号的男生。

保证N是偶数;


思路:


1、直接暴力的话问题的时间复杂度是O(nq);显然直接搞是TLE的,那么考虑思维优化。

首先我们列举出这个问题的一些特性:
①对于操作1,就是所有男生在转圈的移动,显然对于每个人来讲,都要进行。

②对于操作2,就是将所有奇数位子上的男生换到+1的位子上,将所有偶数位子上的男生换到-1的位子上。


2、一开始想做这个题的时候一门心思的考虑怎样操作能够抵消掉一些成对出现的操作2上来。对于这个问题,我萌在纸上多写出几种情况不难发现,对于操作的时候,所有的奇数编号的男生对于操作2的移动反向都是相同的。而且所有的偶数编号的男生对于操作2的移动反向也是相同的。

那么我们找到了一个重要的规律:

由于操作的特性使得奇数编号的男孩子们肯定不会出现相邻的情况,又因为这个特性,那么保证了奇数编号男生的相对位子。

比如1号男生最终到达位子X,那么3号男生到达的位子肯定是X顺时针+2的位子上,那么5号男生到达的位子肯定是X顺时针+4的位子上。

那么同理,对于偶数编号的男孩子们肯定也不会出现相邻的情况,那么又因为这个特性,也保证了偶数编号男生的相对位子。


3、那么我们接下来只要维护编号1的男孩子交换的过程,得到最终的位子,就能轻易的得到编号为3.5.7..................奇数编号的男生们的位子。

同理,我们只要维护编号2的男孩子交换的过程,得到最终的位子,就能轻易的得到编号为2.4.6...........偶数编号的男生们的位子。


Ac代码:

#include<stdio.h>
#include<string.h>
using namespace std;
int a[1000600];
int p[2000600][2];
int ans[1000600];
int main()
{
    int n,q;
    while(~scanf("%d%d",&n,&q))
    {
        int now=1;
        int now2=2;
        memset(ans,0,sizeof(ans));
        for(int i=0;i<q;i++)
        {
            scanf("%d",&p[i][0]);
            if(p[i][0]==1)
            {
                scanf("%d",&p[i][1]);
                now+=p[i][1];
                now2+=p[i][1];
            }
            if(p[i][0]==2)
            {
                if(now%2==1)now+=1;
                else now-=1;
                if(now2%2==1)now2+=1;
                else now2-=1;
            }
            if(now>n)now-=n;
            if(now<1)now+=n;
            if(now2>n)now2-=n;
            if(now2<1)now2+=n;
        }
        int cnt=1;
        int t=n/2;
        while(t--)
        {
            ans[now]=cnt;
            ans[now2]=cnt+1;
            cnt+=2;
            now+=2;
            now2+=2;
            if(now>n)now-=n;
            if(now<1)now+=n;
            if(now2>n)now2-=n;
            if(now2<1)now2+=n;
        }
        for(int i=1;i<=n;i++)
        {
            printf("%d ",ans[i]);
        }
        printf("\n");
    }
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值