coresidual and Euler function and Inverse element
1.同余(coresidual)
1.1 定义和两个常见性质
\(a≡b(\bmod m)<==>m|b-a\)
\(a≡b(\bmod m),a≡b(\bmod n) ==> a≡b(\bmod[m,n])\)
\((k,m)=d,ka≡ka'(mod m) ==> a≡a'(\bmod \frac{m}{d})\)
特别的\((k,m)=1,ka≡ka'(\bmod m) ==>a≡a'(\bmod m)\)
2.线性同余方程
\(ax≡b(mod m),ax+my = b\)两者等价
一开始我们由\(mx≡0(mod m),ax≡b(mod m)\),然后对\(x\)前面的系数辗转相除即可
\(eg.\)
\(100x ≡ 0(mod 100) ①\)
\(87x ≡ 3(mod 100) ②\)
\(①-②\) $ 13x ≡ 97(\bmod 100)③$
$ (-3)\(
\)②-6③$ \(9x ≡ 21(\bmod 100)④\)
$③-④ $ $ 4x ≡ 76(\bmod 100)⑤\(
\)④5-2⑤$ $ x ≡ 69(\bmod 100)$
3.简化剩余系
所有的\(n\)满足\(0<n<=m,(n,m)=1\)构成了一个模m的简化剩余系
欧拉函数\(φ(m)\)
定义:小于m的正整数中与m互质的数的数目
记这样n的个数为\(φ(m)\)
特别的:如果\(p\)是素数,则\(φ(p)=p-1\)
\(φ(m) = mΠp|m(1-1/p)\)
\(eg.30\)中有多少互质的,既不是\(2\)的倍数,也不是\(3\)的倍数,也不是\(5\)的倍数
\(30-30/2-30/3-30/5+30/2/3+30/2/5+30/3/5-30/2/3/5=8\)
\(==>30*(1-1/2)*(1-1/3)*(1-1/5)\)
\(==>30*(1-1/2-1/3-1/5+1/6+1/10+1/15-1/30)\)
\(m以内p1^{e1}*p2^{e2}...pk^{ek}\)
\(==>m(1-1/p1)(1-1/p)...(1-1/pk)\)
4.欧拉定理
如果\((a,m)=1\),那么\(a^{φ(m)}≡1(\bmod m)\)
证明:当\(x\)取遍模\(m\)的化简剩余系时,\(ax\)也取遍模\(m\)的简化剩余系
集合\(P\)小于等于\(m\)的且与\(m\)互质的正整数集合\({x1,x2...xφ(m)}\)
――――\(xi\)与\(m\)互质,\(xi\)模\(m\)后各不相同
集合\(Q\)为{ \(ax1\)%\(m\),\(ax2\)%\(m\)...\(axφ(m)\)%\(m\) }
因为\(a\)与\(m\)互质,所以$a*xi \(%\)m\(也与\)m\(互质,即\)Q\(中各元素均与\)m$互质
\(x1x2…xφ(m) ≡ ax1ax2…axφ(m)(\bmod m)\)
\(x1x2…xφ(m)≡a^{φ(m)}(x1x2…xφ(m))(\bmod m)\)
\(a^{φ(m)} ≡ 1 (\bmod m)\)
即
\(x1x2…xφ(m)≡a^{φ(m)}(x1x2…xφ(m))(\bmod m)\)
\(a^{φ(m)} ≡ 1(\bmod m)\)
5.推论(扩展欧拉定理)
我们知道,对于\(a,m\)互质的情况:
当\((a,m)=1\)时,\(a^{\phi(m)} \bmod m= 1\)
\(a^b \bmod m\)可以转化为 \(a^{b \bmod \phi(m)} \bmod m\),因为每\(a^{\phi(m)} \bmod m = 1\)
接下来我们看不互质的情况:
考虑在不互质的情况下会不会有相似的结论呢?
背景:我们举个例子看看
先说扩欧的结论:
\(a^b \bmod m = a^{b \bmod \phi(m)+\phi(m)} \bmod m\) 当\(b >= \phi(m)\)时
感性的来说:
例题1:BZOJ 3884, 上帝与集合的正确用法
给定一个数字\(p\),求
\(2^{2^2…}\bmod p\)
的值。
理解一下题意:
\(a1 = 2\)
\(ai = 2^{ai-1}\)
当\(ai\)无限大的时候我们知道\(ai \bmod p\)是一个定值
因为这个东西它不一定是互质的,我们只需要把它的指数 \(\bmod \phi(p)+\phi(p)\)求出来,比如说求出来是\(x\),那我们只需要求\(2^x \bmod p\)就行了,然后我们发现它的幂次又是相同的子问题。也就是想要知道指数\(\bmod \phi(m)\)是多少,就要知道这个指数的指数\(\bmod \phi(\phi(m))\)是多少
先说几个结论:
1.除了\(2\)以外,其他数的\(\phi(p)\)都是偶数
2.\(\phi(m)<=\frac{1}{2}m\)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll p;
ll ksm(ll a,ll b,ll m)
{
ll ans = 1,base = a;
while(b>0)
{
if(b&1)
{
ans *= base;
ans %= m;
}
base *= base;
base%=m;
b>>=1;
}
return ans;
}
ll calc(int p)
{
if(p==1)return 0;
int phip = p,q = p;
for(int i = 2;i*i<=q;i++)
{
/*
m以内p1^e1*p2^e2...pk^ek
==>m(1-1/p1)(1-1/p2)...(1-1/pk)
*/
if(q%i==0)
{
phip = phip/i*(i-1);
while(q%i==0)q/=i;
}
}
if(q!=1)phip = phip/q*(q-1);
return ksm(2,calc(phip)+phip,p);
}
void solve()
{
cin>>p;
cout<<calc(p)<<endl;
}
int main()
{
int t;
cin>>t;
for(int i = 1;i<=t;i++)
{
solve();
}
return 0;
}
例题2:CF D. Power Tower
题意:
给定一个数列\(w_1,w_2,...,w_n\)和模数p,每次询问一个区间[l,r],求\(w_l^{w_{l+1}^{w_{l+2}^{{...}^{w_r}}}} \bmod p\)的值
如果你看不懂上面的式子,它其实是这样运算的:
\(x=w_r\),\(x=w_{r-1}^x\),...,\(x=w_l^x\)
题解:
想要知道\(w_l^{w_{l+1}^{w_{l+2}^{{...}^{w_r}}}} \bmod m\)是多少,就要知道它的指数\(\bmod \phi(m)\)是多少,像要知道它的指数\(\bmod \phi(m)\)是多少,就要知道它指数的指数\(\bmod \phi(\phi(m))\)是多少。
我们知道这个\(m\)迭代\(\log\)轮之后会变成\(1\),也就是说我们只需要关注前\(\log\)项,因为后面的是不会影响答案的。
对比上一个例题,上一个例题因为\(b\)一定是\(>\phi(m)\)的,那我们就可以无脑带公式:指数\(\bmod \phi(m)+\phi(m)\)就行了。
但这题,指数是有可能小于\(\phi(m)\)的,那我们每次\(solve(l,r,m)\),如果这个东西\(<m\)我们就返回它原来的值,否则返回模之后加上\(m\)的值.
比如\(x = solve(l+1,r,\phi(m))\),那么当前的值就是\(al^{x}\bmod m\),我们要看\(al^{x}\bmod m\)是不是真的\(<m\),如果是真的\(<m\)我们就返回它原来的值,否则返回模之后加上\(m\)的值。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 101000;
int n,q,m,p[100],a[N],t;
ll ksm(ll a,ll b,ll m)
{
ll ans = 1,base = a;
while(b>0)
{
if(b&1)
{
ans *= base;
ans %= m;
}
base *= base;
base%=m;
b>>=1;
}
return ans;
}
ll phi(int p)
{
int phip = p,q = p;
for(int i = 2;i*i<=q;i++)
{
if(q%i==0)
{
phip = phip/i*(i-1);
while(q%i==0)q/=i;
}
}
if(q!=1)phip = phip/q*(q-1);
return phip;
}
int solve(int l,int r,int x)
{
int q = p[x];
if(l==r)return a[l]<q?a[l]:(a[l]%q+q);
if(q==1)return 1;
int d = solve(l+1,r,x+1);
int ans = ksm(a[l],d,p[x]);
//看a[l]^d < q?
bool isles = true;
if(a[l]!=1)
{
if(d>=30)//2^30次方肯定>q了
isles = false;
else if(pow(a[l],d)>=1e9)isles = false;
else//pow算出的可能有误差
{
int val = ksm(a[l],d,1e9+7);
if(val>=q)isles = false;
}
}
if(!isles)ans += q;
return ans;
}
int main()
{
cin>>n>>m;
p[t++] = m;
while(p[t-1]!=1)
{
p[t] = phi(p[t-1]);
t+= 1;
}
for(int i = 1;i<=n;i++)
{
cin>>a[i];
}
cin>>q;
while(q--)
{
int l,r;
cin>>l>>r;
//0表示mod p[0]
cout<<solve(l,r,0)%m<<endl;
}
return 0;
}
欧拉函数筛法
//筛法:
int phi[3000001];
void phi_table(){
//memset(phi,0,sizeof(phi));
phi[1]=1;
for(int i=2;i<=3000000;i++){
if(!phi[i])
for(int j=i;j<=3000000;j+=i){
if(!phi[j])
phi[j]=j;
phi[j]=phi[j]/i*(i-1);
}
}
}
//单个phi
ll phi(ll n) {
ll ans = n;
for(int i = 2; i*i <= n; i++) {
if(n%i==0) {
ans-=ans/i;
while(n%i==0)
n/=i;
}
}
if(n > 1) ans-=ans/n;
return ans;
}
//线性筛phi
//记得在main里面先调用sieve
const int N=(1<<16)+5;
int n,tot,p[N];
bool flg[N];
void sieve(int n) {
for(int i=2;i<=n;++i) {
if(!flg[i]) p[++tot]=i;
for(int j=1;j<=tot&&i*p[j]<=n;++j) {
flg[i*p[j]]=1;
if(i%p[j]==0) break;
}
}
}
long long phi(long long x) {
long long ans=x;
for(int i=1;i<=tot&&1LL*p[i]*p[i]<=x;++i) {
if(x%p[i]) continue;
ans=ans/p[i]*(p[i]-1);
while(x%p[i]==0) x/=p[i];
}
if(x>1) ans=ans/x*(x-1);
return ans;
}
//同时筛出质数表和欧拉函数表:
//O(nloglogn)
const int MAXN=1000000;
bool check[MAXN+10];
int phi[MAXN+10];
int prime[MAXN+10];
int tot;
void phi_and_prime_table(int N){
memset(check,0,sizeof(check));
phi[1]=1;
tot=0;
for(int i=2;i<=N;i++){
if(!check[i]){
prime[tot++]=i;
phi[i]=i-1;
}
for(int j=0;j<tot;j++){
if(i*prime[j]>N)
break;
check[i*prime[j]]=1;
if(i%prime[j]==0){
phi[i*prime[j]]=phi[i]*prime[j];
break;
}
else{
phi[i*prime[j]]=phi[i]*(prime[j]-1);
}
}
}
}
6.费马小定理(可以看作欧拉定理的特殊版本)
特别的当m是质数,φ(p) = p-1
\(a^{p-1} ≡ 1(\bmod p)\)
- 它可以用来判断大质数也就式Miller-Rabin质数判定
- 它可以用来进行费马小定理降幂也就是
\(a^{k} ≡ a^{k mod (p-1)} (\bmod p)\) - 求解逆元
7.逆元
1>定义
\(ax≡1(mod m)\)
\(x\)是\(a\)的逆元
除法的取模中运用
\(\dfrac{a}{b} ≡ a*b^{-1}(\bmod m)\)
2>求逆元
由于\(a^{φ(m)} ≡1(\bmod m)\)
那么\(a^{-1} ≡ a^{φ(m)-1}(\bmod m)\)
如果m为素数,那么答案为\(a^{m-2}\)
即:\(a^{p-1} ≡ 1(\bmod p)\)(费马小定理)\(==> a*a^{p-2}≡1(\bmod p)\)
用ksm求就ok
否则需将m(合数)分解,或解线性同余方程
\(a^{φ(m)} ≡ 1(\bmod m)\)
$ a{φ(m)-1}≡a(\bmod m)$
特别的:
a.求1~n的逆元
\(inv[i] = (p-p/i)*inv[p \bmod i]\bmod p\)
\(p = (p \bmod i)+\dfrac{p}{i}*i\)
\(0 ≡ (p \bmod i)+\dfrac{p}{i}*i(\bmod p)\)
\(-\dfrac{p}{i}*i ≡ (p \bmod i)\)
\(-\dfrac{p}{i} ≡ i^{-1}(p \bmod i)\)
\(-\dfrac{p}{i}*(p \bmod i)^{-1} ≡ i^{-1}\)
可以看出\(i\)的逆元可以有\(p \mod i\)的逆元逆推得到
需要将\(1\)的逆元初始化为\(1\),因为\(1^{-1}=1^{p-2}\)%\(p = 1\)
注意负数取模,\(-\lfloor\frac{p}{i}\rfloor\)对\(p\)取模需要先将负数\(+p\)变为正数在进行取模操作
//求1~n的逆元
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e7+10;
ll inv[N],n,p;
int main()
{
cin>>p>>n;
inv[1] = 1;
ll ans = 1;
for(int i = 2;i<=n;i++)
{
inv[i] = (p-p/i)*inv[p%i]%p;
ans = ans^inv[i];
}
cout<<ans<<endl;
return 0;
}
inv2..待补充