首页 > 代码库 > BZOJ1965 [Ahoi2005]SHUFFLE 洗牌

BZOJ1965 [Ahoi2005]SHUFFLE 洗牌

x * 2m = l (mod n + 1),故

x = l * (2m)-1 (mod n + 1)

只需要求一下逆元什么的就做完了,注意乘法要用"快速加"的方法。。。否则会爆long long

 

技术分享
 1 /************************************************************** 2     Problem: 1965 3     User: rausen 4     Language: C++ 5     Result: Accepted 6     Time:0 ms 7     Memory:804 kb 8 ****************************************************************/ 9  10 #include <cstdio>11  12 using namespace std;13 typedef long long ll;14  15 ll n, m, l, p;16  17 ll mul(ll x, ll y, ll mod) {18   ll res = 0;19   while (y) {20     if (y & 1) (res += x) %= mod;21     (x <<= 1) %= mod;22     y >>= 1;23   }24   return res;25 }26  27 ll pow(ll x, ll y, ll mod) {28   ll res = 1;29   while (y) {30     if (y & 1) res = mul(res, x, mod);31     x = mul(x, x, mod);32     y >>= 1;33   }34   return res;35 }36  37 int main() {38   scanf("%lld%lld%lld", &n, &m, &l);39   p = n / 2 + 1;40   p = pow(p, m, n + 1);41   printf("%lld\n", mul(p, l, n + 1));42   return 0;43 }
View Code

 

BZOJ1965 [Ahoi2005]SHUFFLE 洗牌