BZOJ 1965 快速幂 + 拓展欧几里得
题目链接: 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; }