大整数相乘取模:
typedef long long LL;
LL Mult(LL a,LL b)
{
LL r=0;
while(b)
{
if(b&1)r=(r+a)%M;
a=(a<<1)%M;
b>>=1;
}
return r;
}
高精度取模:
for(int i=0;i<s.length();++i)
res=(res*10+s[i]-'0')%M;
分数取模(求逆元):
//(m/n)%M
typedef long long LL;
const int M=17;
LL exgcd(LL a,LL b,LL &x,LL &y)
{
if(b==0)
{x=1,y=0;return a;}
else
{
LL x1,y1;
LL d=exgcd(b,a%b,x1,y1);
x=y1,y=x1-a/b*y1;
return d;
}
}
int main()
{
LL tmp,ny,m,n;
cin>>m>>n;
exgcd(n,M,ny,tmp);
ny=(ny+M)%M;
cout<<(m*ny)%M;
return 0;
}
高精度运算:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int M=10000,P=4;
struct BigNum
{
int n[1000],l;
void Init(){l=1;}
//-----------------------------------------
BigNum(){l=1,memset(n,0,sizeof(n));}
BigNum(string s)
{
reverse(s.begin(),s.end());
int Len=s.length()-1;
l=(Len+P)/P;
for(int i=0,j=0,w=1;i<=Len;w*=10,++i)
{
if(i!=0 && i%P==0)w=1,++j;
n[j]+=w*(s[i]-'0');
}
}
//-----------------------------------------
BigNum operator +(const BigNum &x)const
{
BigNum t=*this;
if(x.l>t.l)t.l=x.l;
for(int i=0;i<t.l;++i)
{
t.n[i]+=x.n[i];
if(t.n[i]>=M)
{
t.n[i+1]+=t.n[i]/M;
t.n[i]%=M;
}
}
while(t.n[t.l])
{
t.n[t.l+1]+=t.n[t.l]/M;
t.n[t.l++]%=M;
}
return t;
}
//-----------------------------------------
bool operator <(const BigNum &x)const
{
BigNum t=*this;
if(t.l!=x.l)return t.l<x.l;
for(int i=t.l-1;i>=0;--i)
if(t.n[i]!=x.n[i])return t.n[i]<x.n[i];
return false;
}
BigNum operator -(const BigNum &x)const
{
BigNum t=*this;
if(t<x){printf("-");swap(t,(BigNum &)x);}
for(int i=0;i<t.l;++i)
{
t.n[i]-=x.n[i];
if(t.n[i]<0)
{
t.n[i]+=M;
--t.n[i+1];
}
}
while(!t.n[t.l-1] && t.l>1)--t.l;
return t;
}
//-----------------------------------------
BigNum operator *(const BigNum &x)const
{
BigNum c,t=*this;
c.l=t.l+x.l-1;
for(int i=0;i<t.l;++i)
for(int j=0;j<x.l;++j)
{
c.n[i+j]+=t.n[i]*x.n[j];
if(c.n[i+j]>=M)
{
c.n[i+j+1]+=c.n[i+j]/M;
c.n[i+j]%=M;
}
}
while(c.n[c.l])
{
c.n[c.l+1]+=c.n[c.l]/M;
c.n[c.l++]%=M;
}
return c;
}
BigNum operator *(const int &x)const
{
BigNum c,t=*this;
c.l=t.l;
for(int i=0;i<t.l;++i)
{
c.n[i]+=t.n[i]*x;
if(c.n[i]>=M)
{
c.n[i+1]+=c.n[i]/M;
c.n[i]%=M;
}
}
while(c.n[c.l])
{
c.n[c.l+1]+=c.n[c.l]/M;
c.n[c.l++]%=M;
}
return c;
}
//-----------------------------------------
void Add(int x){if(x||l)n[l++]=x;}//压位会变慢
void Re(){reverse(n,n+l);}
BigNum operator /(const BigNum &x)const
{
BigNum t=*this,r,y;
y.l=0,r.l=t.l;
for(int i=t.l-1;i>=0;--i)
{
y.Add(t.n[i]);
y.Re();
while(!(y<x))y=y-x,r.n[i]++;
while(!y.n[y.l-1] && y.l>=1)--y.l;
y.Re();
}
while(!r.n[r.l-1] && r.l>1)--r.l;
return r;
}
BigNum operator /(const int &x)const
{
BigNum t=*this,r;
r.l=t.l;
int tmp=0;
for(int i=t.l-1;i>=0;--i)
{
tmp+=t.n[i];
if(tmp>=M)r.n[i]+=tmp/x,tmp%=x;
tmp*=M;
}
while(!r.n[r.l-1] && r.l>1)--r.l;
return r;
}
//-----------------------------------------
void Print()
{
printf("%d",n[l-1]);
for(int i=l-2;i>=0;--i)
printf("%0*d",P,n[i]);
printf("\n");
}
};
矩乘:
struct Mat
{
long long m[N][N];
Mat(){memset(m,0,sizeof(m));}
void unit()
{
for(int i=0;i<N;++i)
m[i][i]=1;
}
Mat operator *(const Mat &x)const
{
Mat t=*this,c;
for(int i=0;i<N;++i)
for(int j=0;j<N;++j)
{
c.m[i][j]=0;
for(int k=0;k<N;++k)
c.m[i][j]=(c.m[i][j]+t.m[i][k]*x.m[k][j])%M;
}
return c;
}
Mat Pow(long long x)
{
Mat t=*this,r;
r.unit();
while(x)
{
if(x&1)r=r*t;
t=t*t;
x>>=1;
}
return r;
}
void Debug()
{
for(int i=0;i<N;++i)
{
for(int j=0;j<N;++j)
printf("%08I64d ",m[i][j]);
printf("\n");
}
printf("\n");
}
};