luogu P1226 【模板】快速幂||取余运算
今天是2019.6.4 距离NOIP2019还有157天
今天是我阴历生日
出去吃完饭后赶快回来写代码了
这又是一道模板题
原理我就不多说了
但这里我要复习之前学的位运算
这种运算符能加快运算速度
虽然是常数级的优化 但卡个常卡好了暴力也能更丝滑柔顺
常用的位运算符有 & ^ << >> ~
这里设两个二进制数 a, b;c为位运算的结果
1.&是a和b的对应位都是1,c的该位才是1,否则为0
example: a % 2 等价于 a & 1
2.^是a和b的对应位相同,c的该位是0,否则为1
example: 如果要在n个数中(这些数中每个相同的数字都有偶数个但只有一个数有奇数个)筛出出现奇数次的数
如果用异或的话就能将重复偶数次的数全部去掉而出现奇数次的数还会留下一个
3.<<是将a * 2
example: a * 2 等价于 a << 1
推广: a * (2 m) 等价于 a << m
4.>>是将a / 2(整除)
example: 33 / 2 == 16 等价于 33 >> 1 == 16
5.~是取a的相反数再-1
example: ~a 等价于 -a-1 ~5 == -6
6.个人技巧
判断奇偶性的时候原来要写 if(x % 2 == 0)
现在就写成 if((x & 1) ^ 1)
原来计算 100 % 8
现在可以用 100 - ((100 >> 3) << 3)
总之位运算这个东西能卡常
GG说过:能快一点也叫快 你都要去尝试
下面是代码
#include<cstdio> #include<cstring> #include<cmath> #include<cctype> #include<cstdlib> #include<string> #include<iostream> #include<algorithm> #include<set> #include<map> #include<queue> #include<stack> #include<vector> #define enter puts("") #define space putchar(' ') using namespace std; typedef long long ll; ll read() { ll op = 1, ans = 0; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-') op = 0; ch = getchar(); } while(ch >= '0' && ch <= '9') { ans *= 10; ans += ch - '0'; ch = getchar(); } return op ? ans : -ans; } void write(ll x) { if(x < 0) { x = -x; putchar('-'); } if(x >= 10) write(x / 10); putchar(x % 10 + '0'); } ll b, p, k; ll quickpow(ll a, ll b, ll c) { if(b == 1) return a % c; if((b & 1) ^ 1) { ll bc = quickpow(a, b / 2, c); return bc * bc % c; } ll bc = quickpow(a, b / 2, c); bc = bc * bc % c; bc = bc * a % c; return bc; } int main() { b = read(), p = read(), k = read(); if(p == 0) { printf("%lld^%lld mod %lld=%lld", b, p, k, 1 % k); enter; return 0; } printf("%lld^%lld mod %lld=%lld", b, p, k, quickpow(b, p, k) % k); return 0; }