一、欧拉函数的求法
欧拉函数表示一个数的简化剩余系的元素数。
对于一个数p,它的欧拉函数值即为[1,p)内与p互质的数的个数
数组形式一般是Phi(x)
1、O(√n)求φ(n)
int zch(int x) {
int ret=x;
for(int i=2;i*i<=x;i++){
if(x%i==0) ret-=ret/i;
while(x%i==0) x/=i;
}
if(x>1) ret-=ret/x;
return ret;
}
2、O(n)求φ(1)~φ(n)
const int maxn=1e6+7;
int cnt,v[maxn],p[maxn],phi[maxn];
void PHI(int n){
for(int i=2;i<=n;i++) {
if(!v[i]){
p[++cnt]=i;
phi[i]=i-1;
v[i]=i;
}
for(int j=1;j<=cnt;j++){
if(1ll*p[j]*i>n) break;
int t=p[j]*i;
v[t]=p[j];
if(i%p[j]==0){
phi[t]=phi[i]*p[j];
break;
}
else phi[t]=phi[i]*phi[p[j]];
}
}
}
讲解:欧拉函数详解
3、所有不是质数的数的最小质因子是2或3或5或7。再细分如果n是偶数则它的最小素因子是2,如果n是奇数,它的最小素因子是3/5/7。
4、欧拉函数中有一个推论:1到n中与n互质的和==phi(n)*n/2。 可以看一下 证明
一道欧拉函数与容斥相结合的题:hdu-5514 -----这题挺有意思的
5、扩展欧拉定理
情况一:
降幂公式一
(a,p)==1时,a^b==a^(b % φ(p))
若q为素数, a^b==a^(b % (p-1) )
例
求 2^n % mod , 已知mod为素数
ll qpow(ll a, int b){
ll ans=1;
while(b){
if(b&1) ans=(ans*a)%mod;
a=(a*a)%mod;
b>>=1;
}
return ans;
}
string a;
ll ans;
int main(){
cin>>a;
int n=a.size();
for(int i=0;i<n;i++) ans=(ans*10+a[i]-'0')%(mod-1);
cout<<qpow(2,ans);
}
情况二:
降幂公式二、三
求 a^b mod p
1<=a<=1e9 , 1<=b<=1e2000000 , 1<=p<=1e8
扩展欧拉定理模板
int a,b,p,phi;
char x;
bool f;
ll qpow(ll a, int b){
ll ans=1;
while(b){
if(b&1) ans=(ans*a)%p;
a=(a*a)%p;
b>>=1;
}
return ans;
}
ll zch(int x) {
ll ret=x;
for(ll i=2;i*i<=x;i++){
if(x%i==0) ret-=ret/i;
while(x%i==0) x/=i;
}
if(x>1) ret-=ret/x;
return ret;
}
int main(){
scanf("%d%d",&a,&p);
phi=zch(p);
while(!isdigit(x=getchar()));
while(isdigit(x)){
b=b*10+x-'0';
if(b>=phi){
f=1;
b%=phi;
}
x=getchar();
}
if(f) b+=phi;
printf("%lld",qpow(a,b));
}
二、莫比乌斯函数
莫比乌斯函数讲解
1、莫比乌斯函数的线性筛(就比普通线性筛多4行)
const int maxn=1e5+7;
int prime[maxn],cnt,mu[maxn]; //保存质数 , 质数的个数 , 保存n的莫比乌斯函数值
bool judge[maxn]; //标记是否为质数,true表示是质数,flase表示合数;
void mul(){
mu[1]=1;
for(int i=2;i<=maxn;i++){
if(judge[i]){
prime[++cnt]=i;
mu[i]=-1;
}
for(int j=1;j<=cnt&&i*prime[j]<maxn;j++){
judge[i*prime[j]]=0;
if(i%prime[j]==0){
mu[i*prime[j]]=0;
break;
}
else mu[i*prime[j]]=-mu[i];
}
}
}
做题注意点:
1、数学几何中,数据往往是double,比较两个数是否相等,得用fabs(a,b)<1e-10.
2、已知两条直线的各两个点(共4个点),求交点时,不要用斜率做,除法太多,数据会卡精度。有公式:见例题
3、 atan 和 atan2 都是求反正切函数,如:有两个点 point(x1,y1), 和 point(x2,y2);
那么这两个点形成的斜率的角度计算方法分别是:
float angle = atan( (y2-y1)/(x2-x1) );
或
float angle = atan2( y2-y1, x2-x1 );
atan 和 atan2 区别:
1:参数的填写方式不同;
2:atan2 的优点在于 如果 x2-x1等于0 依然可以计算,但是atan函数就会导致程序出错;
结论: atan 和 atan2函数,建议用 atan2函数;
4、acos() 函数返回一个数的反余弦。
提示:acos(-1) 返回 Pi 的值。
acos(number);
• number
• 必需。
• 规定一个数,范围在 -1 到 1 之间。
• 返回值
• number 的反余弦。
• 如果 number 不在 -1 到 1 之间的范围,则返回 NAN。
有一道用到上述三角函数的题:链接