模擬 nbut1225 NEW RDSP MODE I
阿新 • • 發佈:2017-07-18
研究 tar 復雜 function pac efi 找規律 ref 時間
傳送門:點擊打開鏈接
題意:輸入n。m,x。剛開始有一個1~n的排列。然後定義了一種操作。是將數組中的偶數位數字選出來,依照順序放到數組最前面,奇數位依照順序放到偶數位的後面,進行m次這種操作。輸出之後前x個數字
思路:找到循環節T,利用T去約m,然後再將非常小的m拿去模擬,輸出前x個
一開始就想到找循環節,,剛開始僅僅想到去用找規律的方法去找到通項公式,可是找了好久就是沒找到。盡管感覺理論上肯定是有的T^T
可是找規律的時候發現了非常多特點:T一定小於等於n。還有就是最剛開始的時候數字1是在第一個位置。當數字1再次出如今第一個位置的時候,剛好就是一個循環節!
所以。我們僅僅須要模擬1的位置,一直模擬到1出如今第一個位置時,循環節就算出來了。復雜度O(n)。1的位置還是非常好模擬的,由於僅僅研究了一個數字而已,還是非常好找到遞推式子的。
找到循環節T之後。我們令m=m%T.這樣m就變成<=n的了。然後就能夠再次模擬
接下來,我們對前x個數字,分別倒著模擬m次。由於如今的m<=n,所以復雜度O(xn),倒著模擬的公式也是非常好找的
最後看別人的代碼才發現,,事實上模擬的時候。就是一個高速冪(fuck)
總之。還是有些感慨。有時候不一定模擬就非要找到通項公式。找到辦法能在較短的時間內算出通項公式,這樣也並不算差~
#include<map> #include<set> #include<cmath> #include<stack> #include<queue> #include<cstdio> #include<string> #include<vector> #include<cstring> #include<iostream> #include<algorithm> #include<functional> #define FIN freopen("input.txt","r",stdin) #define FOUT freopen("output.txt","w+",stdout) using namespace std; typedef long long LL; typedef pair<int, int> PII; const int MX = 1e5 + 5; const int INF = 0x3f3f3f3f; int find_t(int n) { int p = 1, ret = 0; while(true) { ret++; if(p % 2) p = n / 2 + (p + 1) / 2; else p = p / 2; if(p == 1) return ret; } } int solve(int p, int n, int m) { for(int i = 1; i <= m; i++) { if(p * 2 <= n) p = p * 2; else p = (p - n / 2 - 1) * 2 + 1; } return p; } int main() { int n, m, x;//FIN; while(~scanf("%d%d%d", &n, &m, &x)) { int t = find_t(n); for(int i = 1; i <= x; i++) { printf("%d%c", solve(i, n, m % t), i == x ?'\n' : ' '); } } return 0; }
模擬 nbut1225 NEW RDSP MODE I