3637. 解密信件(遞歸回溯)
阿新 • • 發佈:2018-12-12
oxx 總是喜歡給 ultmaster 寫信,由於某些原因,這些信的內容又不能被人看見。但傳信的過程中,信中資訊的洩露又不可避免,於是 oxx 發明了一種信內容資訊的加密方式。ultmaster 拿到了 oxx 的加密程式:
char letter[]; void encrypt(l, r) { if (l < r) { reverse letter[l..r]; k = (r - l + 1) / 2; encrypt(l, l + k - 1); encrypt(l + k, r); } }
其中 reverse letter[l..r]
letter
從 l 到 r(閉區間)的子串倒置。
對於某個長度為 n,下標從 1 開始的字串要進行加密,只要呼叫 encrypt(1, n)
即可。
由於 ultmaster 有超強的理解能力,所以 ultmaster 只需要知道信裡面某些位置的資訊,就能得知整封信的內容。而 oxx 寫了太多的信給 ultmaster 。所以 ultmaster 會有 T 次詢問,每一次詢問其中一封信的一個位置 x,表示加密後的信裡的位置,他想知道這個位置在加密前的信裡是在什麼位置。
眾所周知,oxx 有很多話想說,所以信會很長很長。
Input
第一行一個整數 T (1≤T≤1 000),表示詢問的個數。
接下來的 T 行,每行兩個整數 n 和 x (1≤x≤n≤1018),表示信的長度和詢問的位置。
Output
包含 T 行,每行一個整數,表示對於每一個詢問的答案。
Examples
input
4 4 1 4 2 4 3 4 4
output
3 4 1 2
Note
樣例解釋:1234 → 43|21 → 3|4|1|2.
題目大概:
給出加密的字母的位置,要求給出它的原來位置。
思路:
它是遞迴加密,那麼用回溯來解密。
程式碼:
#include <bits/stdc++.h> using namespace std; #define ll long long const int mod=1e9+7; const int maxn=2e5+10; const double pi=acos(-1.0); ll dfs(ll l, ll r,ll x) { if (l < r) { ll k = (r - l + 1) / 2; if(x<k+l) { ll dx=dfs(l, l + k-1 ,x); return r+l-dx; } else { ll dx=dfs(l + k, r,x); return r+l-dx; } } else return x; } int main() { int t; scanf("%d",&t); while(t--) { ll n,k; scanf("%lld%lld",&n,&k); printf("%lld\n",dfs(1,n,k)); } return 0; }