a^b
题目链接http://oj.daimayuan.top/course/13/problem/565
边界问题:b=0并且p=1的时候,快速幂板子返回的是1,实际是0,在qmi()后面%p就可以了,或者在qmi()板子里面初始化成LL res = 1 % p;
#include
using namespace std;
typedef long long LL;
LL qmi(LL a, LL b, LL mod){
LL res = 1;
while(b){
if(b&1) res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
int main(){
int a, b, p;
scanf("%d %d %d", &a, &b, &p);
printf("%d\n", qmi(a, b, p) % p);
return 0;
}
起床困难综合症
参考:https://www.acwing.com/solution/content/15383/
1. 常见的一种二进制贪心(和&,|,^搭配),二进制越靠前的位权重越大,能使得前面的位为1,就使得前面的位为1,否则后面就算全是1也弥补不回来
2. 按位考虑,&,|,^这些运算只和当前位相关,和其他位无关,所以可以按位考虑,而且这样枚举的情况可以从n->logn
3. 如何确定当前枚举到的位能不能选1,如果在枚举前面的时候,n中可以是1,但是最终选择了0,后面就可以随便选了,使用last标记下即可
#include
using namespace std;
typedef long long LL;
const int N = 1e5+10;
int op[N], x[N];
int n, m;
int cal(int t, int i){
int res = t << i;
for(int j = 1; j <= n; j ++){
if(op[j] == 1){
res = res & (x[j] & (1 << i));
}
else if(op[j] == 2){
res = res | (x[j] & (1 << i));
}
else{
res = res ^ (x[j] & (1 << i));
}
}
return res;
}
int main(){
scanf("%d %d", &n, &m);
for(int i = 1; i <= n; i++){
char s[4];
scanf("%s %d", s, &x[i]);
if(s[0] == 'A') op[i] = 1;
else if(s[0] == 'O') op[i] = 2;
else op[i] = 3;
}
int res = 0;
int last = 0;
for(int i = 31; i >= 0; i --){
if(last || (m >> i & 1)){
int A = cal(1, i), B = cal(0, i);
if(A > B) res += A;
else res += B, last = 1;
}
else res += cal(0, i);
}
printf("%d\n", res);
return 0;
}