今天做了BC第三十三场,
http://bestcoder.hdu.edu.cn/contests/contest_show.php?
cid=571
B题是一道高速幂的题目 比赛时没有细想 直接上了 结果被hack了。才发现取摸的数是小于10^18,中间的结果可能会爆long long。于是学习了新姿势 —— 高速乘法。
事实上这东西和高速幂简直一样 优点就是中间过程能够取摸了。a*b相当于有b个a想加 是不是和a^b有b个a相乘很类似?注意这里b不能是负数 否则没法用高速乘。
#include <cstdio> #include <string> #include <cmath> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define N 100005 #define mod 100 typedef __int64 LL; LL p; LL Mul(LL a, LL b) { LL res = 0; while(b) { if(b & 1) { res = (res + a) % p; } b >>= 1; a = (a + a) % p; } return res; } LL POW(LL a, LL n) { LL res = 1; while(n) { if(n & 1) { res = Mul(res, a); } n >>= 1; a = Mul(a, a); } return res; } int main() { LL n; while(~scanf("%I64d %I64d", &n, &p)) { if(n == 1) { printf("%I64d ", n % p); } else printf("%I64d ", ((POW(2, n) - 2) + p) % p); } return 0; }