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. Flask 运用Xterm实现交互终端

    Xterm是一个基于X Window System的终端仿真器(Terminal Emulator).Xterm最初由MIT开发,它允许用户在X Window环境下运行文本终端程序.Xterm提供了一 ...

  2. MongoDB 6.0 单实例基于用户角色实现授权登录

    现代数据库系统能够存储和处理大量数据.因此,由任何一个用户单独负责处理与管理数据库相关的所有活动的情况相对较少.通常,不同的数据库用户需要对数据库的某些部分具有不同级别的访问权限:某些用户可能只需要读 ...

  3. vim的各种快捷键

    目录 一.准备一份用于练习的文件 二.命令模式下的快捷键 1.移动光标 2.删除文字 3.复制粘贴 4.撤销上一次操作 5.恢复上一次撤销的操作 6.查找 7.替换单个字符 8.光标移动到最左边 9. ...

  4. 深度解读DBSCAN聚类算法:技术与实战全解析

    探索DBSCAN算法的内涵与应用,本文详述其理论基础.关键参数.实战案例及最佳实践,揭示如何有效利用DBSCAN处理复杂数据集,突破传统聚类限制. 关注TechLead,分享AI全维度知识.作者拥有1 ...

  5. [HAOI2018] 字串覆盖

    [HAOI2018]字串覆盖 题目描述 小C对字符串颇有研究,他觉得传统的字符串匹配太无聊了,于是他想到了这 样一个问题. 对于两个长度为n的串A, B, 小C每次会给出给出4个参数s, t, l, ...

  6. C++ Qt开发:ToolBar与MenuBar菜单组件

    Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍ToolBar ...

  7. Tampermonkey(油猴)的获取方法

    介绍: Tampermonkey中有大量的脚本,可以方便我们在日常的上网使用. 有那么一句话说:没有了Tampermonkey(油猴)我都不知道该如何上网. 获取Tampermonkey的步骤: 1. ...

  8. 内核模块(.ko) 开发入门

    内核模块时指的是在操作系统内核中动态加载的一段代码,它可以扩展和增强操作系统的功能.内核模块通常用于为操作系统添加新的设备驱动程序.文件系统.网络协议栈等功能. 内核模块是以二进制形式存在的(*.ko ...

  9. ThreadLocal底层源码解析

    ThreadLocal底层源码解析 ThreadLocal:顾名思义的意思是本地线程或者局部线程的意思,其真正含义是希望多个线程之间拥有自己的局部变量,多个线程间拥有自己的私人变量,在多线程间不被共享 ...

  10. Windows 激活系统提示0x80072F8F错误代码的解决方法(刷新你的认知)

    Server2008.Server2012.Server2016.Win7.Win10都适用 https://blog.csdn.net/happyxjbf/article/details/10591 ...