题目描述

你有一叠标号为1到n的卡片。
你有一种操作,可以重排列这些卡片,操作如下:
1.将卡片分为前半部分和后半部分。
2.依次从后半部分,前半部分中各取一张卡片,放到新的序列中。
例如,对卡片序列(1,2,3,4,5,6)操作后的结果为(4,1,5,2,6,3)。
现在你有一个初始为(1,2,3,⋯,n)的卡片序列,你需要求出进行m次操作之后第x个位置上的卡片的标号。

输入

第一行包含三个非负整数n,m,x。

输出

输出一行一个数,表示答案。

样例输入

6 2 3

样例输出

6

提示

对于60%的数据,m≤107。
对于100%的数据,0≤n,m,x≤109。
数据有梯度,保证n为偶数。


【题解】:

请移步到这里,卡片即可,我也是看了别人题解做的。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 ll ex_gcd( ll a , ll b , ll &x , ll &y ){
 5     if( b == 0 ){
 6         x = 1 ;
 7         y = 0 ;
 8         return a ;
 9     }
10     ll r = ex_gcd( b , a%b , y , x );
11     y -= x * ( a/b );
12     return r ;
13 }
14 ll qpow( ll a , ll b , ll mod ){
15     ll ans = 1 ;
16     while( b ){
17         if( b & 1 ){
18             ans = ans * a % mod ;
19         }
20         a = a * a % mod ;
21         b >>= 1 ;
22     }
23     return ans ;
24 }
25 ll Gcd , n , m , p , x , y , a , b ;
26 int main()
27 {
28     ios_base :: sync_with_stdio(false);
29     cin.tie(NULL) , cout.tie(NULL) ;
30     cin >> n >> m >> p ;
31     a = qpow(2,m,n+1) , b = n + 1 ;
32     Gcd = ex_gcd( a , b , x , y );
33
34     b /= Gcd , p /= Gcd ;
35     x = ( x % b ) * p % b ;
36
37     if( x < 0 ) x += b ;
38
39     cout << x << endl ;
40     return 0;
41 }
02-11 16:31