Problem Description
给出N
for(i = 1; i <= N; i ++) a[i] = i;
solve(n,a[]) {
if(n == 1) return;
将奇数下标的数赋给a1,假设有len1个
将偶数下标的数赋给a2,len2个
solve(len1,a1)
solve(len2,a2)
for(int i = 1; i <= len1; i ++) a[i] = a1[i];
for(int i = 1; i <= len2; i ++) a[i + len1] = a2[i];
}
给出M个查询,1. 查询执行完solve的数组a中第i个数是什么,2. 查询原数组a中第i个数现在的位置
Input
多组数据
对于每组数据,第一行N,M(1 <= N <= 10^18, 1 <= M <= 10^5)
接下来M行,每行两个数x,y (1 <= x <= 2, 1 <= y <= n)
x = 1,查询执行完solve的数组a中第i个数是什么
x = 2, 查询原数组a中第i个数现在的位置
Output
每个查询输出一行,你的答案
Sample Input
4 2 1 2 2 4 6 4 1 1 1 5 1 3 2 4
Sample Output
3 4 1 6 3 6
Hint
例子N = 4,{1,2,3,4} -> {1,3} + {2,4} = {1,3,2,4}
N = 6,{1,2,3,4,5,6}-> {1,3,5} + {2,4,6} = {1,5} + {3} + {2,6} + {4} = {1,5,3,2,6,4}
1 #include <iostream> 2 #include <stdio.h> 3 #include <math.h> 4 #include <string.h> 5 #include <algorithm> 6 using namespace std; 7 #define ll long long 8 ll fun2(ll y,ll n) 9 { 10 if(y==1) 11 return 1; 12 if(y&1) 13 { 14 return fun2(((y>>1)+1),((n+1)>>1)); 15 } 16 else 17 { 18 return ((n+1)>>1)+fun2(y>>1,n>>1); 19 } 20 } 21 ll fun1(ll y,ll n) 22 { 23 if(y==1) 24 return 1; 25 ll m=(n+1)>>1; 26 if(y<=m) 27 { 28 return (fun1(y,m)<<1)-1; 29 } 30 else 31 { 32 return (fun1(y-m,n>>1)<<1); 33 } 34 } 35 int main() 36 { 37 ll n,x,y,ans; 38 int m,i,j; 39 while(scanf("%lld%d",&n,&m)!=EOF) 40 { 41 for(i=0;i<m;i++) 42 { 43 scanf("%lld%lld",&x,&y); 44 if(x==1) 45 { 46 printf("%lld\n",fun1(y,n)); 47 } 48 else 49 { 50 printf("%lld\n",fun2(y,n)); 51 } 52 } 53 } 54 return 0; 55 }