GMOJ P3403 【数列变换】

Description

开始有一初始数列 a = [ a 1 , a 2 , a 3 , ⋅ ⋅ ⋅ , a n ] a=[a_{1},a_{2},a_{3},···,a_{n}] a=[a1,a2,a3,,an] ,定义 f ( a , k ) = [ a 2 , a 3 , ⋅ ⋅ ⋅ , a k , a 1 , a k + 2 , a k + 3 , ⋅ ⋅ ⋅ , a 2 k , a k + 1 ⋅ ⋅ ⋅ ] f(a,k)=[a_{2},a_{3},···,a_{k},a_{1},a_{k+2},a_{k+3},···,a_{2k},a_{k+1}···] f(a,k)=[a2,a3,,ak,a1,ak+2,ak+3,,a2k,ak+1] ,也就是把 a a a 分段,每段 k k k 个,若最后不足 k k k 个时,将剩下的组成新的一段,每段第一个移成该段最后一个。

f ( f ( f ( f ( f ( 1 , 2 , 3 , ⋅ ⋅ ⋅ , n ) , 2 ) , 3 ) , ⋅ ⋅ ⋅ ) , n ) f(f(f(f(f(1,2,3,···,n),2),3),···),n) f(f(f(f(f(1,2,3,,n),2),3),),n) 的结果。

1 ≤ n ≤ 1 0 6 1\leq n\leq 10^{6} 1n106

Solution

考虑使用 模拟找规律 来解题。

操作中是将数列按每 k k k 个为一段,将第一个移到最后一个的位置,其他然后往前补一格。

但我们很快可以发现,有一种等价的做法是:将第 1 1 1 个移到 k + 1 k+1 k+1 个的位置,第 k + 1 k+1 k+1 个移到第 2 k + 1 2k+1 2k+1 的位置,一直到第 x k + 1 xk+1 xk+1 个移到 n + 1 n+1 n+1 的位置,第 2 2 2 个到第 n + 1 n+1 n+1 个组成的序列和之前的做法组成的序列是一样的。

那问题就变成了在数列中移动是 k k k 的倍数加 1 1 1 的数的问题。

然后这道题目就做完了,具体细节详见代码

Code

#include<cstdio>
int n,a[2000001],an,t;
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        a[i]=i;
    for(register int i=2;i<=n;i++)
    {
        an=a[i-1];
        for(register int j=2*i-1;j<=n+i-2;j+=i)
        {
            t=an;
            an=a[j];
            a[j]=t;
        }
        a[n+i-1]=an;
    }
    for(int i=n;i<=2*n-1;i++)
    {
        printf("%d ",a[i]);
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值