python爬蟲(下)--bs+re+urllib+xlwt+sqlite3
阿新 • • 發佈:2021-02-02
(本篇沒有涉及公式的推導)
尤拉函式:
就是對於一個正整數n,小於n且和n互質的正整數的個數記做φ(n) 。
尤拉函式的通式:
φ(n) = n * ( 1 - 1 / p1) ( 1 - 1 / p2 ) ( 1 - 1 / p3 ) * ( 1 - 1 / p4 )……( 1 - 1 / pn )
其中p1,p2……pn為n的所有質因子,n是不為0的整數。(唯一和1互質的數就是1本身)。
所以根據通式可以打出以下程式碼:
ll eular(ll n)
{
ll ans=n;
for(int i=2;i*i<=n;i++)
{
if (n%i==0)
{
ans=ans/i*(i-1);
while(n%i==0)
n=n/i;
}
}
if(n>1) ans=ans/n*(n-1);
return ans;
}
尤拉定理:
在數論中,尤拉定理,(也稱費馬——尤拉定理)是一個關於同餘的性質。尤拉定理表明,若n和a為正整數,且n,a互質,則:
尤拉降冪
第一個要求a和p互質,第二個和第三個是廣義的尤拉降冪,但要求b和φ( p)的關係 。
模板:
求A^BmodC
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1e6+10;
char b[N];
LL a,c;
LL quick_pow(LL x,LL y,LL z)
{
LL ans=1;
while(y)
{
if(y%2) ans=ans*x%z;
x=x*x%z;
y=y/2;
}
return ans;
}
LL phi(LL n) //求尤拉函式
{
LL ans=n;
for(int i=2;i*i<=n;i++)
{
if(n%i==0)
{
ans=ans-ans/i;
while(n%i==0)
n=n/i;
}
}
if(n>1) ans=ans-ans/n;
return ans;
}
int main()
{
cin>>a>>b>>c;
int len=strlen(b);
LL p=phi(c);
LL ans=0;
for(int i=0;i<len;i++)
ans=(ans*10+b[i]-'0')%p;
ans=ans+p;
cout<<quick_pow(a,ans,c)<<endl;
//system("pause");
return 0;
}
經典擴充套件
(洛谷)P4139 上帝與集合的正確用法
題目傳送門:
題目大意:
首先我們可以根據擴充套件尤拉定理:
得到:
很顯然這是一個遞迴的式子,邊界條件為p=1,此時式子的值為0。而對於φ§,我們可以線性篩處理。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1e7+10;
int n,tot,p[N],phi[N];
bool flag[N];
void pre()
{
phi[1]=1;
for(int i=2;i<N;i++)
{
if(!flag[i])
{
p[++tot]=i;
phi[i]=i-1;
}
for(int j=1;j<=tot&&i*p[j]<N;j++)
{
flag[i*p[j]]=1;
if(i%p[j]==0)
{
phi[i*p[j]]=phi[i]*p[j];
break;
}
else
phi[i*p[j]]=phi[i]*phi[p[j]];
}
}
}
LL quick_pow(LL x,LL y,LL mod)
{
LL ans=1;
while(y)
{
if(y%2) ans=ans*x%mod;
x=x*x%mod;
y=y/2;
}
return ans;
}
LL solve(int p)
{
if(p==1) return 0;
return quick_pow(2,solve(phi[p])+phi[p],p);
}
int main()
{
pre();
int t;
scanf("%d",&t);
while(t--)
{
int p;
scanf("%d",&p);
printf("%lld\n",solve(p));
}
//system("pause");
return 0;
}