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. GeminiDB新特性:让Redis广告频控爱不释手的exHASH

    本文分享自华为云社区<GeminiDB新特性:让Redis广告频控爱不释手的exHASH>,作者:GeminiDB-Redis博客 . exHash类型是一种支持Field过期的新型数据类 ...

  2. Curator

  3. MyBatisPlus简介

    MyBatisPlus特性 国内的一个网站 网站地址简介 | MyBatis-Plus (baomidou.com)

  4. SpringBoot整合Liquibase

    1.是什么? Liquibase官网 Liquibase是一个开源的数据库管理工具,可以帮助开发人员管理和跟踪数据库变更.它可以与各种关系型数据库和NoSQL数据库一起使用,并提供多种数据库任务自动化 ...

  5. Selenium-ActionChains动作链(针对鼠标、滚轮等操作

    https://www.selenium.dev/documentation/webdriver/actions_api/ 注意:对于滚轮的操作,只支持chrome浏览器,且selenium版本在4. ...

  6. NetSuite 开发日记 —— 库存详细信息记录更改数量问题

    详细报错: "type":"error.SuiteScriptError","name":"USER_ERROR",&q ...

  7. 算法2:Hanoi塔

    汉诺(Hanoi)塔 一.背景介绍 在印度,有这么一个古老的传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针.印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了 ...

  8. libGDX游戏开发之游戏纹理精灵切割(十六)

    libGDX游戏开发之游戏纹理精灵切割(十六) libGDX系列,游戏开发有unity3D巴拉巴拉的,为啥还用java开发?因为我是Java程序员emm-国内用libgdx比较少,多数情况需要去官网和 ...

  9. k8s初始化pod-pod标签

    目录 initContainers(初始化容器) 静态pod pod的调度策略(将pod指派给特定节点) initContainers(初始化容器) k8s在1.3版本的时候引入了一个初始化容器(in ...

  10. Head First 的学习之道

    <Head First 设计模式>是一本好书,正如书的封面上说的那样,这是一本重视大脑的学习指南.里面提到了一些学习方法,可以尝试下,看看哪些对你有用: 1. 慢一点,理解的越多,需要记得 ...