returna+p*(((b-a)*u)%q);//根据同余定理,计算
}
/*----------------------------------------------vlong.h----------------------------------------------------*/
//长整数类,可随意定义其长度
classvlong
{//公有成员函数
public:
//重载常用算术运算符
friendvlongoperator+(constvlong&x,constvlong&y);
//友元函数operator+实现对算术运算符'+'的重载
friendvlongoperator-(constvlong&x,constvlong&y);
//友元函数operator-实现对算术运算符'-'的重载
friendvlongoperator*(constvlong&x,constvlong&y);
//友元函数operator*实现对算术运算符'*'的重载
friendvlongoperator/(constvlong&x,constvlong&y);
//友元函数operator/实现对算术运算符'/'的重载
friendvlongoperator%(constvlong&x,constvlong&y);
//友元函数operator%实现对算术运算符'%'的重载
vlong&operator+=(constvlong&x);//'+='
vlong&operator-=(constvlong&x);//'-='
//重载常用比较运算符
friendinlineintoperator!
=(constvlong&x,constvlong&y){returnx.cf(y)!
=0;}
//友元内联函数实现对常用比较运算符operator!
=的重载
friendinlineintoperator==(constvlong&x,constvlong&y){returnx.cf(y)==0;}
//友元内联函数实现对常用比较运算符operator==的重载
friendinlineintoperator>=(constvlong&x,constvlong&y){returnx.cf(y)>=0;}
//友元内联函数实现对常用比较运算符operator>=的重载
friendinlineintoperator<=(constvlong&x,constvlong&y){returnx.cf(y)<=0;}
//友元内联函数实现对常用比较运算符operator<=的重载
friendinlineintoperator>(constvlong&x,constvlong&y){returnx.cf(y)>0;}
//友元内联函数实现对常用比较运算符operator>的重载
friendinlineintoperator<(constvlong&x,constvlong&y){returnx.cf(y)<0;}
//友元内联函数实现对常用比较运算符operator<的重载
//构造函数
vlong(unsignedx=0);//构造函数声明
vlong(constvlong&x)//构造函数声明
~vlong();//析构函数
operatorunsigned();//操作,无符号
vlong&operator=(constvlong&x);//赋值函数
//私有数据成员及成员函数
private:
classvlong_value*value;//类
intnegative;//整型变量
intcf(constvlongx)const;//常数
voiddocopy();//拷贝
friendclassmonty;//友元类
};
vlongmodexp(constvlong&x,constvlong&e,constvlong&m);//?
?
?
vlonggcd(constvlong&X,constvlong&Y);//求最大因子
vlongmodinv(constvlong&a,constvlong&m);//Euclid算法
/*---------------------------------------vlong.cpp*-------------------------------------------------------*/
#include"vlong.h"//引入vlong.h
classvlong_value;//类的声明
/*-------------------------------以下为flex_unit类定义与实现----------------------------*/
classflex_unit//类的声明
{
unsigned*a;//内存unsignedint单元数组
unsignedz;//分配单元数
public:
//公有成员函数
unsignedn;//已使用的单元数(只读属性)
flex_unit();//构造函数
~flex_unit();//析构函数
voidclear();//已使用单元数n清0
unsignedget(unsignedi)const;//获取第i个单元值
voidset(unsignedi,unsignedx);//设置第i个单元值
voidreserve(unsignedx);//扩展存储区
//有时间要求的乘法
voidfast_mul(flex_unit&x,flex_unit&y,unsignedn);
};
//按索引获取单元值
unsignedflex_unit:
:
get(unsignedi)const
{
if(i>=n)return0;//如果i超过n,则返回0
returna[i];//否则,返回第i个单元数
}
voidflex_unit:
:
clear()//清空
{
n=0;//n为0
}
flex_unit:
:
flex_unit()//构造函数
{
z=0;//z初始化为0
a=0;//a初始化为0
n=0;//n初始化为0
}
flex_unit:
:
~flex_unit()//析构函数
{
unsignedi=z;//获取分配单元数
while(i)//
{
i-=1;//i递减1
a[i]=0;
}
delete[]a;//删除
}
voidflex_unit:
:
reserve(unsignedx)//扩展存储区
{
if(x>z)//如果x大于z
{
unsigned*na=newunsigned[x];//生成新的na
for(unsignedi=0;idelete[]a;//删除a
a=na;//na赋值给a
z=x;//x赋值给z
}
}
//根据索引设置元素值
voidflex_unit:
:
set(unsignedi,unsignedx)
{
if(i{
a[i]=x;//第i个单元值置为x
if(x==0)//如果x等于0
while(n&&a[n-1]==0)//去除高位0
n-=1;//n每次递减1
}
elseif(x)//否则?
{
reserve(i+1);//扩展,i+1
for(unsignedj=n;j
a[i]=x;//第i个单元值置为x
n=i+1;//n置为i+1
}
}
#defineBPU(8*sizeof(unsigned))//unsignedint类型bit数
#definelo(x)((x)&((1<<(BPU/2))-1))//unsignedint低半部分
#definehi(x)((x)>>(BPU/2))//unsignedint高半部分
#definelh(x)((x)<<(BPU/2))//使低半部分左移至高半部分
voidflex_unit:
:
fast_mul(flex_unit&x,flex_unit&y,unsignedkeep)//快速乘法
{
//*this=(x*y)%(2**keep)
unsignedi,limit=(keep+BPU-1)/BPU;//运算结果单元数
reserve(limit);//扩展为limit
for(i=0;ia[i]=0;//初始化为0
unsignedmin=x.n;//n?
if(min>limit)//取较小者
min=limit;
for(i=0;i//对取得的已使用的单元数n与运算结果单元数之间的较小者内存单元进行处理
{
unsignedm=x.a[i];//获取每个内存单元值
unsignedc=0;//初始化为0
unsignedmin=i+y.n;//获取当前位置后第n个位置
if(min>limit)min=limit;//取min与limit之间的较小者
for(unsignedj=i;j{
//此处代码为运算关键,可使用机器或汇编代码以加快速度,c:
a[j]=a[j]+c+m*y.a[j-i];
unsignedw,v=a[j],p=y.a[j-i];//?
v+=c;c=(vw=lo(p)*lo(m);v+=w;c+=(v?
?
w=lo(p)*hi(m);c+=hi(w);w=lh(w);v+=w;c+=(v?
?
w=hi(p)*lo(m);c+=hi(w);w=lh(w);v+=w;c+=(v?
?
c+=hi(p)*hi(m);//?
?
?
a[j]=v;//?
?
?
}
while(c&&j{
a[j]+=c;
c=a[j]j+=1;
}
}
keep%=BPU;//去除不必要的bit
if(keep)
a[limit-1]&=(1<while(limit&&a[limit-1]==0)//计算使用单元数
limit-=1;
n=limit;//limit赋值给n
};
/*---------------------------------以上为flex_unit类定义与实现----------------------------*/
/*-------------------------------以下为vlong_value类定义与实现----------------------------*/
classvlong_value:
publicflex_unit//继承自flex_unit,负责vlong类内存管理
{//共有数据成员及成员函数
public:
unsignedshare;//共有
intis_zero()const;//测试大数是否为0
inttest(unsignedi)const;//测试第i位(bit)值是否为0
unsignedbits()const;//获取大数位(bit)数
intcf(vlong_value&x)const;//比较大小
voidshl();//左移
voidshr();//右移
voidshr(unsignedn);//左移n位
voidadd(vlong_value&x);//加法
voidsubtract(vlong_value&x);//减法
voidinit(unsignedx);//初始化函数
voidcopy(vlong_value&x);//拷贝
operatorunsigned();//转换至unsignedint类型,不安全
vlong_value();//构造函数
voidmul(vlong_value&x,vlong_value&y);//乘法
voiddi