算法进阶:0x01 位运算

摘要:
0x3F3F3F3F的两倍不超过0x7F7F7F7F,memset。一共k+1次,k为logb级别。

一、快速幂的模板代码 a^b%p

#include<iostream>
using namespacestd;
intmain()
{
    inta,b,p;
    cin>>a>>b>>p;
    int res = 1 %p;
    while(b)
    {
        if (b & 1) res = res * 1ll * a %p;
        b >>= 1;
        a = a * 1ll * a %p;
    }
    cout<<res<<endl;
}

注意点:

1、转换成long long类型可以直接乘1ll,作用与(long long)相同,范围大概为10^19,int为2 147 483 647。

2、以2^7为例,7 = 4(2^2) + 2(2^1) + 1(2^0);二进制形式为111,b&1为获取最后一位是否为1,b>>=1舍弃最后一位。

3、如果测试数据为123456789 0 1,res=1没有%p的话,那么结果就是1,正确应为0,所以应该初始化res就%p,res = 1 % p。

4、memset(a, val, sizeof(a))把数值val(0x00~0xFF)填充到数组a的每个字节上,一个int占用4个字节,所以用memset只能赋值出“每8位都相同”的int。0x3F3F3F3F(1 061 109 567)的两倍不超过0x7F7F7F7F(2 147 483 647),memset(a, 0x3F, sizeof(a))。0xFFFFFFFF为-1。

二、如果a, b, p范围是10^18,求a*b%p

1、那么为了不超过范围,首先得用usigned long long,2*10^19。乘法转化为加法,a^b = a * a * …… * a。a * b = a + a + ……+a。

a * 1 = 2^0 * a,

a * 2 = 2^1 * a,

a * 4 = 2^2 * a,

a * 8 = 2^3 * a,

a * 2^k = 2^k * a。

一共k+1次,k为logb级别。

#include<iostream>
using namespacestd;
typedef unsigned long longULL;
intmain()
{
    ULL a,b,p;
    cin>>a>>b>>p;
    ULL res = 0;
    while(b)
    {
        if (b & 1) res = (res + a) %p;
        b >>= 1;
        a = a * 2 %p;
    }
    cout<<res<<endl;
}

最短Hamilton路径:

算法进阶:0x01 位运算第1张

算法进阶:0x01 位运算第2张

算法进阶:0x01 位运算第3张

算法进阶:0x01 位运算第4张

免责声明:文章转载自《算法进阶:0x01 位运算》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Idea 热部署插件JRebel 安装与环境配置-上海尚学堂Java培训OSG的节点访问下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

UVA 690 PipelineScheduling 位运算+dfs+剪枝

一开始最容易想到间隔最多为n,但是结点还是太多了,需要优化。 预处理:预判一下并保存下一个可以放的位置距离之前的距离。这样可以减少很多判断。 最优化剪枝:如果当前长度+剩下没放的程序*最短间隔如果大于等于ans,那么对答案没有贡献,可以剪去。 优化:占用和不占用两种状态,如果横向来看可以压缩为int,判断时用上为运算。 此题挂在长度的枚举上,我把长度为n给...

memset函数使用

函数原型 void *memset(void *s,int c,size_t n); 功能 将已开辟内存空间 s 的首 n 个字节的值设为值 c。 头文件  #include<memory.h>  1. memset是以字节为单位,初始化内存块。 当初始化一个字节单位的数组时,可以用memset把每个数组单元初始化成任何你想要的值,比如, c...

关于memset的几个易错点

memset(void *s,int ch,size_t n); 作用:将s中当前位置后面的n个字节用 ch 替换并返回 s  注意这里是“字节”而非单位长度,memset不会考虑各个类型的单位长度,只是处理字节。所以使用的时候应该用如下的格式: memset(a,b,n*sizeof(int));//这里以Int为例。 -----------------...

关于memset的使用

今天学了一下有关memset的使用 当然还是从网上找的资料 有一篇博客讲的挺好的 http://www.xuebuyuan.com/1442940.html 我总结一下今天学到的几点 1、关于memset的赋值原理 void *memset(*s,   c, size_t n);  其中s为要开始赋值的首地址   c 位要赋值成的   n位长度 memse...

为枚举类型添加描述信息 this 扩展 泛型约束 位运算[转]

为枚举类型添加描述信息 this 扩展 泛型约束 位运算 2011年10月13日 星期四 上午 10:09     在开发应用中,我们经常用枚举来简化程序。但是让人头的是总得枚举一个别名Alias用于显示或者描述该枚举值,这时候如果我们采用if或者switch的方法来进行判读也可以,但是有点不够优雅。下面来给大家分享一下我的实现方法。今天同事把博客园里的...

数据结构基础之memset---有memset 抛出的int 和 char 之间的转换和字节对齐

今天晚上,在做滤波算法时,里面用到很多float 和int 以及char 之间的类型强制转换,后面滤波完发现图片有些区域块,有过度曝光的白光,我就跟踪,以为是char 字符数字数据溢出问题,加了0-255的判断,然后打印,发现强制转换后的int类型数据多处出现负数,很奇怪,后面写了个测试程序,慢慢的问题出来了 : #include <stdio.h&...