题解:左右横跳。
原题来源:Codeforces
翻译来源:LFYZOJ
分析: 手动模拟之后,我们发现,对于一个数x,他第1次向前移动的格数为2*(n-x)+1;第i次为i=2i-1。也就是说,只有第一次移动的是奇数格。
然后,找规律。
查询x为奇数时,这个位置的数字是从未移动的。
如果是偶数,我们可以判断出它移动前的位置,直到某一次是移动了奇数格,也就是这个数的第一次移动,由此确定它的值。
下面是代码:
1 #include<iostream> 2 using namespace std; 3 typedef long long ll; 4 ll n, x; 5 int q; 6 ll ans(ll a){ 7 if (a%2) return (a+1)/2; 8 ll step=n-(a/2); 9 if (step%2) return (a+step+1)/2; 10 else return ans(a+step); 11 } 12 int main(){ 13 cin>>n>>q; 14 while(q--){ 15 cin>>x; 16 cout<<ans(x)<<endl; 17 } 18 return 0; 19 }
"Hello World!"