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;
}

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