BC Round#33 B(10的18次方,快速乘法+快速幂取余)

由于数据很大,因此做乘法时每一步都要取余,然后再相加(快速乘法),因为是2的n次方-2,所以还是要用到快速幂取余。
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <cmath>
 6 #include <string>
 7 #include <map>
 8 #include <stack>
 9 #include <vector>
10 #include <set>
11 #include <queue>
12 #define maxn 1005
13 #define MAXN 2005
14 #define mod 1000000009
15 #define INF 0x3f3f3f3f
16 #define pi acos(-1.0)
17 #define eps 1e-6
18 #define lson rt<<1,l,mid
19 #define rson rt<<1|1,mid+1,r
20 #define FRE(i,a,b)  for(i = a; i <= b; i++)
21 #define FRL(i,a,b)  for(i = a; i < b; i++)
22 #define mem(t, v)   memset ((t) , v, sizeof(t))
23 #define sf(n)       scanf("%d", &n)
24 #define sff(a,b)    scanf("%d %d", &a, &b)
25 #define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
26 #define pf          printf
27 #define DBG         pf("Hi
")
28 typedef __int64 ll;
29 using namespace std;
30 
31 ll n,p;
32 
33 ll quickmul(ll x,ll m)  ///快速乘法,x与m的每一位相乘取余
34 {
35     ll re=0;
36     while(m)
37     {
38         if(m&1)
39         {
40             re=(re+x)%p;
41         }
42         x=(x+x)%p;
43         m>>=1;
44         printf("%lld",m);
45     }
46     return re;
47 }
48 
49 ll pow_m(ll a,ll n) ///快速幂取余
50 {
51     ll ret=1;
52     ll temp=a%p;
53     while (n)
54     {
55         if (n&1) ret=quickmul(ret,temp)%p;
56         temp=quickmul(temp,temp)%p;
57         n>>=1;
58     }
59     return ret;
60 }
61 
62 int main()
63 {
64     int i,j;
65     while (~scanf("%I64d%I64d",&n,&p))
66     {
67         if (n==1)       ///特判
68         {
69             if (p==1) pf("0
");
70             else pf("1
");
71             continue;
72         }
73         pf("%I64d
",(pow_m(2,n)-2+p)%p);
74     }
75     return 0;
76 }
View Code
原文地址:https://www.cnblogs.com/ACMERY/p/4339744.html