A题:a^b

https://ac.nowcoder.com/acm/contest/996/A

题目描述

求 a 的 b 次方对 p 取模的值,其中 0 <= a,b,p <= 10^9

输入描述:

三个用空格隔开的整数a,b和p。

输出描述:

一个整数,表示a^b mod p的值。

实例

输入: 2 3 9

输出: 8

思路

这道题是要先算出a的b次幂再对其结果进行求模(取余),因为b最大可为1e+9,按普通做法来做时间复杂度就太大了,显然这样过不了题,

能快速算a的b次幂,就能减小时间复杂度,快速幂就是一种不错的方法。

什么是快速幂

快速幂是一种简化运算底数的n次幂的算法,理论上其时间复杂度为 O(log₂N),而一般的朴素算法则需要O(N)的时间复杂度。简单来说快速幂其实就是抽取了指数中的2的n次幂,将其转换为时间复杂度为O(1)的二进制移位运算,所以相应地,时间复杂度降低为O(log₂N)。

代码原理

以 \(a^{13}\) 为例,

先把指数13化为二进制就是1101,把二进制数字1101直观地表现为十进制则是如下的等式:

\[13 = 1 * (2^3) + 1 * (2^2) + 0 * (2^ 1) + 1 * (2^0)
\]

这样一来 \(a^{13}\) 可以如下算出:

\[a^{13} = a ^ {(2^3)} * a ^ {(2^2)} * a ^ {(2^0)}
\]

完整AC代码如下

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;//将long long类型取个别名:ll类型,为了方便 int power(int a, int b, int mod) {
ll ans = 1 % mod;
for (; b; b >>= 1) {
if (b & 1) ans = ans * a % mod;
a = (ll)a * a % mod;//显式转化为ll类型进行高精度计算,再隐式转化为int
}
return ans;
} int main() {
//freopen("in.txt", "r", stdin);
ios::sync_with_stdio(false), cin.tie(0);
int a, b, mod;
cin >> a >> b >> mod;
cout << power(a, b, mod) << endl;
}

B题:Raising Modulo Numbers

与上面A题写法一样

typedef long long ll;
int _;
// 稍微优化下上方代码:update 21/01/28
ll qpow(ll a, ll b, ll mod) {
ll ans = 1;
a %= mod;
for (; b; a = a * a % mod, b >>= 1)
if (b & 1) ans = ans * a % mod;
return ans;
}
int main() {
// freopen("in.txt", "r", stdin);
ios_base::sync_with_stdio(false), cin.tie(0);
ll M, N;
for (cin >> _; _--;) {
cin >> M >> N;
ll a, b, ans = 0;
while (N--) {
cin >> a >> b;
ans = (ans + qpow(a, b, M)) % M;
}
cout << ans << endl;
}
}

C题:64位整数乘法

链接:https://ac.nowcoder.com/acm/contest/996/C

思路:

类似快速幂的思想,把整数b用二进制表示,即

\[b = c_{k - 1}2^{k - 1} + c_{k -2}2^{k - 2} + ... + c_02^0
\]
typedef long long ll;
int main() {
//freopen("in.txt", "r", stdin);
ios::sync_with_stdio(false), cin.tie(0);
ll a, b, p; cin >> a >> b >> p;
ll ans = 0;
for (; b; b >>= 1) {
if (b & 1)ans = (ans + a) % p;
a = (a << 1) % p;
}
cout << ans << endl;
}

D题:最短Hamilton路径

链接:https://ac.nowcoder.com/acm/contest/996/D

解题思路


AC代码:

#define ms(a,b) memset(a,b,sizeof a)
int e[21][21], b[1 << 21][21], n;
int main() {
//freopen("in.txt", "r", stdin);
ios::sync_with_stdio(false), cin.tie(0);
cin >> n;
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
cin >> e[i][j];
ms(b, 0x3f); b[1][0] = 0;
for (int i = 0; i < 1 << n; ++i)
for (int j = 0; j < n; ++j) if (i >> j & 1)
for (int k = 0; k < n; ++k) if (~(i >> k) & 1)//if ((i ^ 1 << j) >> k & 1)
b[i + (1 << k)][k] = min(b[i + (1 << k)][k], b[i][j] + e[j][k]);
cout << b[(1 << n) - 1][n - 1] << endl;
}

例题:[NOI2014]起床困难综合征

题意:

链接:[NOI2014] 起床困难综合症

贪心从高位到低位枚举,检验当前位在初始值为\(0\) 情况下的答案是否可以为\(1\) ,如果不能则检验当前位初始值能否为 \(1\),并检验当前位在初始值为 \(1\) 情况下的答案是否可以为 \(1\)。

int n, m, x;
string str;
pair<string, int> a[100005];
int work(int bit, int now) { // 用参加的第 bit 位进行n次运算
for (int i = 1; i <= n; ++i) {
int x = a[i].second >> bit & 1;
if (a[i].first == "AND")
now &= x;
else if (a[i].first == "OR")
now |= x;
else
now ^= x;
}
return now;
}
int main() {
ios_base::sync_with_stdio(false), cin.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; ++i) {
cin >> str >> x;
a[i] = make_pair(str, x);
}
int val = 0, ans = 0;
for (int bit = 29; bit >= 0; bit--) {
int res0 = work(bit, 0), res1 = work(bit, 1);
if (val += (1 << bit) <= m && res0 < res1)
val += (1 << bit), ans += (res1 << bit);
else
ans += (res0 << bit);
}
cout << ans << "\n";
return 0;
}

0x01 基本算法-位运算的更多相关文章

  1. 0x01 基本算法-位运算 a^b

    #include<bits/stdc++.h>using namespace std;int power(int a, int b, int p){    int ans = 1%p;   ...

  2. Apriori算法-位运算-C语言

    原文地址:http://blog.csdn.net/liema2000/article/details/6118423 //////////////////////////////////////// ...

  3. java加密解密算法位运算

    一.实例说明 本实例通过位运算的异或运算符 “ ^ ” 把字符串与一个指定的值进行异或运算,从而改变每个字符串中字符的值,这样就可以得到一个加密后的字符串.当把加密后的字符串作为程序输入内容,异或运算 ...

  4. LeetCode | 289. 生命游戏(原地算法/位运算)

    记录dalao的位运算骚操作 根据百度百科 ,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在 1970 年发明的细胞自动机. 给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细 ...

  5. 剑指offer—算法之位运算(二进制中1的个数)

    位运算: 左移:m<<n将m左移n位,左移后低位补充0: 右移:m>>n将m右移n位,右移后高位补充的是符号位,负数补充1,整数补充0.(正数的边界值为(1,ox7FFFFFF ...

  6. 位运算之——按位与(&)操作——(快速取模算法)

    学习redis 字典结构,hash找槽位 求槽位的索引值时,用到了 hash值 & sizemask操作, 其后的scan操作涉及扫描顺序逻辑,对同模的槽位 按一定规则扫描! 其中涉及位运算 ...

  7. PHP算法学习(5) 位运算

    svn地址:svn://gitee.com/zxadmin/live_z 2019年2月14日11:38:46 <?php /* * 位运算学习笔记 * * 1,php所有的数都是有符号的,无法 ...

  8. 【Java基础】14、位运算之——按位与(&)操作——(快速取模算法)

    学习redis 字典结构,hash找槽位 求槽位的索引值时,用到了 hash值 & sizemask操作, 其后的scan操作涉及扫描顺序逻辑,对同模的槽位 按一定规则扫描! 其中涉及位运算 ...

  9. 位运算(Bit Manipulation)在算法中的应用

    最近刷LettCode,遇到几个没思路的算法题,都是关于位运算的 # 136 Single Number Given a non-empty array of integers, every elem ...

  10. 基于DP+位运算的RMQ算法

    来源:http://blog.csdn.net/y990041769/article/details/38405063 RMQ算法,是一个快速求区间最值的离线算法,预处理时间复杂度O(n*log(n) ...

随机推荐

  1. WPS JS宏

    WPS JS宏 1 JS宏基础 1.1 JS宏基础 1.1.1 JS录制新宏 如果在WPS表格中要编写控制表格的代码,却又不知道如何编写,那么可以使用JS录制新宏功能,接下来录制几个常用的操作: 录制 ...

  2. 【python】无法安装pip,报错ImportError: No module named 'pip'解决方案

    命令提示符输入以下代码即可 python -m ensurepip

  3. eclipse的问题

    在我使用eclipse的时候出现的一个问题 就是因为汉化之后出现的问题 问题的解决办法 点击帮助 关于 安装细节 选中Babel Language Pack for rt.rap in Chinese ...

  4. 5分钟安装Kubernetes+带你轻松安装istio服务网格指南

    上次我跟大家简单介绍了一下Kubernetes的各个组件及其含义,本期本来计划带领大家一起学习一些常用命令,但我认为这种方式可能无法达到学习的效果.有可能你们会直接忘记,甚至可能没有兴趣去学.我也理解 ...

  5. JDK1.8下载阿里云盘不限速

    JDK1.8下载阿里云盘不限速 专门给你写篇jdk文章容纳方便下载 废话不多说直接上链接 「jdk-8u202-windows-x64.exe」https://www.aliyundrive.com/ ...

  6. Ubuntu 安装MySQL 8.0.23及以上版本

    首先如果当前linux中没有wget,那么我们可以考虑使用sudo apt-get install wget来安装wget命令 Ubuntu自带的源只能安装MySQL5.7版本,这里去MySQL官网安 ...

  7. javacv实现直播流

    javacv实现直播流 javacv从入门到入土系列,音视频入门有一点门槛的延迟大概是2~4秒之间, 依赖 <!-- 需要注意,javacv主要是一组API为主,还需要加入对应的实现 --> ...

  8. 轻量化动态编译库 Natasha v8.0 正式发布!

    .NET8.0 与 动态编译 Hello 各位小伙伴,我于 2024年1月10日 发布了 Natasha 一个全新的里程碑版本 v8.0,对于老用户而言,此次发布版本号跨度较大,是因为我决定使用新的版 ...

  9. Jenkins简介及安装配置详解:开启持续集成之旅

    Jenkins简介及安装配置详解:开启持续集成之旅 一.Jenkins介绍 Jenkins是一个开源的.用Java编写的持续集成和持续交付(CI/CD)工具.它提供了一种简单易用的方式来自动化构建.测 ...

  10. java常用正则表达式工具

    public class RegexUtils { /** * 是否是无效手机格式 * @param phone 要校验的手机号 * @return true:符合,false:不符合 */ publ ...