NBUT1225 NEW RDSP MODE I(快速幂,规律):

G - NEW RDSP MODE I

NBUT - 1225

题意:

​ 给你三个数n,n,mm,xx。代表刚开始有1n1 到n刚好n个数,现在让你将序列变换mm次,问你变换mm次之后前xx个的值;

​ 序列每一次变换的规则:将其中奇数位置的数取出,按顺序放在最后面。

思路:

​ 因为变换的规则比较简单,所以我们可以根据这次位置 计算出 变换前的位置,向上推导mm​次即可,那么我们可以先写出变换公式。

假设位置x变换前在位置last,那么我们不难推出下列公式:

  • 如果 x<=n/2x<=\lfloor n/2 \rfloor​ 则有 last=2xlast=2*x​

  • 否则 则有last=2(xn/2)1last=2*(x-\lfloor n/2 \rfloor)-1

这样规律显示的不够清楚,我们可以这样写

  • 当n为偶数时候:

    • 如果x<=nx<=n​,则有 last=2xlast=2*x​.
    • 否则last=2(xn/2)1=2xn1last=2*(x-n/2)-1=2*x-n-1​
  • 当n为奇数的时候:

    • 如果x<=(n+1)/2x<=(n+1)/2, 则有last=2xlast=2*x
    • 否则last=2(x(n+1)/2)1last=2*(x-(n+1)/2)-1last=2xnlast=2*x-n

​ 那么我们可以将位置xx向上推导mm次,最后得到的位置就是要求的位置xx的值。但是mm太大,这种根本不可行,我们现在试图找一个更好的公式。

​ 我们有没有发现一个规律,**当nn​为奇数的时候 lastlast​ 可以表示为 last=2x %nlast=2*x\ \%n​ ,(如果last=0last=0​表示last=n);**那么我们向上求mm​次,则乘以2m2^m​取余nn​即可 (快速幂不难做到这一点)。但是当nn​位偶数的时候怎么办呢?我们发现当nn​位偶数时nn个数​的结果与n+1n+1​的结果一模一样。

因为第n+1n+1​个数每次都是最后一个奇数,他总会放在最后面,不影响前nn​个数的相对顺序

​ 所以我们当nn​为偶数时,我们可以把n+1n+1​变为奇数,然后位置xx​的转换mm​次前的位置为 x2mx*2^m%n+1​

所以程序思想分下面三步:

  • 如果nn为偶数就让n=n+1n=n+1
  • 转换mm次后位置xx的值为val=x2mval=x*2^m%n
  • 如果valval00则输出nn,否则输出valval

代码:

#include<queue>
#include<iostream>
#include<string.h>
#include<cstdio>
#include<iostream>
#include<algorithm>
#define mset(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef pair<int,int> P;
typedef long long ll;
const int maxn=2e4+100;
int t;
ll quickPow(ll a,ll b,ll mod){
    ll ans=1ll;
    while(b){
        if(b&1) ans=ans*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return ans;
}
int main()
{
    ll n,m,x,ans;
    while(cin>>n>>m>>x){
       if(n%2==0)   n++;
       ll mid=quickPow(2,m,n);
       for(ll i=1;i<=x;++i){
        if(i>1)
            cout<<" ";
         ans=i*mid%n;
         if(ans==0)
            cout<<n;
         else
            cout<<ans;
       }
       puts("");
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章