题目链接: http://www.lydsy.com/JudgeOnline/problem.php?id=1965
AHOI2005 Day1
是一道找规律题… 不难发现初始为x的牌在经过m轮洗牌之后的位置为x*(2^k) % (n+1)。然后就是一个二元线性不定方程,拓欧解之即可。
方程为: (2^k)%(n+1)*x + (n+1)*y = L
// BZOJ 1965
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
#define read(x) scanf("%lld", &x)
LL n, m, L;
void exgcd(LL a, LL b, LL &x, LL &y) {
if (b==0) { x=1; y=0; return; }
exgcd(b, a%b, y, x);
y-=x*(a/b);
}
LL gcd(LL a, LL b) {
if (!(a%b)) return b;
return gcd(b, a%b);
}
LL quick_pow(LL a, LL n, LL mod) {
LL ret=1;
while (n>0) {
if (n%2) ret=(ret*a)%mod;
a=(a*a)%mod;
n/=2;
}
return ret;
}
// p*x + n*y = L
int main()
{
read(n); read(m); read(L);
n++;
LL p=quick_pow(2, m, n), d, x=0, y=0;
d=gcd(p, n);
p/=d; n/=d; L/=d;
exgcd(p, n, x, y);
x=x*L%n;
while (x<0) x+=n;
printf("%lld\n", x);
return 0;
}