您的位置:首页 > 其它

[备战NOI同步赛]快速幂模板(二分/位运算)

2014-07-03 21:57 302 查看
/*
快速幂模板
By:qpswwww(ZYK)
含二分快速幂、位运算快速幂
*/

#define LONG long long int

int MOD; //取模
LONG normalPow(LONG base,LONG pow) //二分法求base^pow快速幂
{
if(pow==0) return 1;
LONG out;
out=normalPow(base,pow/2);
out*=out;
out%=MOD;
if(pow&1) //pow为奇数,再乘一次base
{
out*=base;
out%=MOD;
}
return out;
}
LONG fastPow(LONG base,LONG pow) //位运算求快速幂
{
/*
eg:
11<=> 1     0     1     1
2^3*1 2^2*0 2^1*1 2^0*1
*/
int out=1;
while(pow!=0)
{
if(pow&1) //这一位要乘
{
out*=base;
out%=MOD;
}
base*=base;
pow>>=1;
}
return out;
}

例题:BZOJ 1008 HNOI 2008 越狱

Description

监狱有连续编号为1...N的N个房间,每个房间关押一个犯人,有M种宗教,每个犯人可能信仰其中一种。如果相邻房间的犯人的宗教相同,就可能发生越狱,求有多少种状态可能发生越狱

Input

输入两个整数M,N.1<=M<=10^8,1<=N<=10^12

Output

可能越狱的状态数,模100003取余

Sample Input

2 3

Sample Output

6

HINT

6种状态为(000)(001)(011)(100)(110)(111)

Source

题目的具体分析请看我的另一篇博文/article/8152082.html,这里只贴上使用快速幂模板的代码

/*
快速幂模板
By:qpswwww(ZYK)
含二分快速幂、位运算快速幂
*/
#include <stdio.h>

#define LONG long long int

int MOD; //取模
LONG normalPow(LONG base,LONG pow) //二分法求base^pow快速幂
{
if(pow==0) return 1;
LONG out;
out=normalPow(base,pow/2);
out*=out;
out%=MOD;
if(pow&1) //pow为奇数,再乘一次base
{
out*=base;
out%=MOD;
}
return out;
}
LONG fastPow(LONG base,LONG pow) //位运算求快速幂
{
/*
eg:
11<=> 1     0     1     1
2^3*1 2^2*0 2^1*1 2^0*1
*/
int out=1;
while(pow!=0)
{
if(pow&1) //这一位要乘
{
out*=base;
out%=MOD;
}
base*=base;
pow>>=1;
}
return out;
}
int main()
{
//结果:m^n-m*(m-1)^(n-1)
LONG m,n,compSet,uniSet,ans;
MOD=100003;
scanf("%lld%lld",&m,&n);
compSet=normalPow(m-1,n-1);
uniSet=normalPow(m,n);
compSet*=m;
compSet%=MOD;
ans=uniSet-compSet;
if(ans<0) ans+=MOD;
printf("%lld\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: