白天拍了一天马原视频,欠了一堆实验报告没写,昨晚cf鸽了,牛客数学专题班欠一堆题,外加感冒,今晚的cf应该也鸽了…这两场补题看情况了
先开始第一个问题:求正整数 n ( 1 ≤ n ≤ 1 0 7 ) n(1\le n\le 10^7) n(1≤n≤107)的所有正因数的个数, q ( 1 ≤ q ≤ 1 0 5 ) q(1\le q\le10^5 ) q(1≤q≤105)次询问 例题
我们规定
n
n
n的正因子数目为
d
(
n
)
d(n)
d(n),
n
n
n的最小质因子出现次数为
e
(
n
)
e(n)
e(n)
n
=
p
1
k
1
p
2
k
2
.
.
.
p
c
k
c
(
p
1
<
p
2
<
.
.
.
<
p
c
)
n={p_1}^{k_1}{p_2}^{k_2}...{p_c}^{k_c}({p_1}\lt{p_2}\lt...\lt{p_c})
n=p1k1p2k2...pckc(p1<p2<...<pc)
d
(
n
)
=
∏
i
=
1
c
(
k
i
+
1
)
d(n)=\prod_{i=1}^c(k_i+1)
d(n)=∏i=1c(ki+1)
e
(
n
)
=
k
1
e(n)=k_1
e(n)=k1
显然
d
(
n
)
d(n)
d(n)是一个积性函数: 对于
g
c
d
(
a
,
b
)
=
1
gcd(a,b)=1
gcd(a,b)=1,
d
(
a
×
b
)
=
d
(
a
)
×
d
(
b
)
d(a\times b)=d(a)\times d(b)
d(a×b)=d(a)×d(b)恒成立
线性筛 d ( n ) d(n) d(n):
#include <bits/stdc++.h>
using namespace std;
const int N=1e7+10;
typedef long long ll;
ll d[N],e[N],prime[N],c;
void solve(){
d[1]=1;
for(int i=2;i<N;i++){
if(d[i]==0){
prime[c++]=i;
d[i]=2;
e[i]=1;
}
for(int j=0;1LL*prime[j]*i<N;j++){
if(i%prime[j]==0){
d[i*prime[j]]=d[i]/(e[i]+1)*(e[i]+2);
e[i*prime[j]]=e[i]+1;
break;
}
d[i*prime[j]]=d[i]*d[prime[j]];
e[i*prime[j]]=1;
}
}
}
int main(){
ll q,n;
scanf("%lld",&q);
solve();
while(q--){
scanf("%lld",&n);
printf("%lld\n",d[n]);
}
return 0;
}
华华给月月出题
求
A
n
s
=
⊕
i
=
1
N
(
i
N
m
o
d
(
1
0
9
+
7
)
)
Ans=\oplus_{i=1}^N(i^N mod(10^9+7))
Ans=⊕i=1N(iNmod(109+7)) (
⊕
\oplus
⊕表示异或和)
(
1
≤
N
≤
1.3
×
1
0
7
)
(1\le N\le 1.3\times 10^7)
(1≤N≤1.3×107)
对于
f
(
i
)
=
i
N
f(i)=i^N
f(i)=iN,显然有
f
(
i
×
j
)
=
f
(
i
)
×
f
(
j
)
f(i\times j)=f(i)\times f(j)
f(i×j)=f(i)×f(j)恒成立,那么我们称这种函数为完全积性函数
那么我们对每个素数直接用快速幂求出
f
f
f,线性筛求出其余的
f
f
f,最后再求异或和即可
Code:
#include <bits/stdc++.h>
using namespace std;
const int N=2e7+10,mod=1e9+7;
typedef long long ll;
ll power(ll a,ll b){
ll ans=1;
for(;b;b>>=1){
if(b&1) ans=ans*a%mod;
a=a*a%mod;
}
return ans;
}
ll prime[N],fac[N],n,cnt;
bool vis[N];
void solve(){
fac[1]=1;
for(int i=2;i<=n;i++){
if(!vis[i]) {
prime[++cnt]=i;
fac[i]=power(i,n);
}
for(int j=1;j<=cnt&&i*prime[j]<=n;j++){
vis[i*prime[j]]=1;
fac[i*prime[j]]=fac[i]*fac[prime[j]]%mod;
if(i%prime[j]==0) break;
}
}
}
int main(){
cin>>n;
solve();
ll ans=0;
for(int i=1;i<=n;i++) ans^=fac[i];
cout<<ans<<endl;
return 0;
}
下面我们介绍一下线性筛求莫比乌斯函数
莫比乌斯函数:
μ
(
n
)
=
{
1
若
n
=
1
;
(
−
1
)
k
若
n
无
平
方
因
子
数
,
且
n
=
p
1
∗
p
2
.
.
.
.
p
c
;
0
若
n
有
平
方
因
子
数
\mu(n)=\begin{cases} 1\qquad若n=1;\\(-1)^k 若n无平方因子数,且n=p_1*p_2....p_c;\\0 \qquad若n有平方因子数\end{cases}
μ(n)=⎩⎪⎨⎪⎧1若n=1;(−1)k若n无平方因子数,且n=p1∗p2....pc;0若n有平方因子数
显然
μ
(
n
)
\mu(n)
μ(n)是一个积性函数,那么如何用线性筛求出这个积性函数
我们考虑三种情况如下:
1.
n
=
p
j
c
n=p_j^c
n=pjc,那么有:
μ
(
p
j
)
=
−
1
\mu(p_j)=-1
μ(pj)=−1,
μ
(
n
)
=
0
,
c
>
1
\mu(n)=0,c>1
μ(n)=0,c>1
2.
n
=
i
×
p
j
n=i\times p_j
n=i×pj且
p
j
∣
i
p_j\mid i
pj∣i,那么有:
μ
(
n
)
=
0
\mu(n)=0
μ(n)=0
3.
n
=
i
×
p
j
n=i\times p_j
n=i×pj且
p
j
∤
i
p_j\nmid i
pj∤i,那么有:
μ
(
n
)
=
−
μ
(
i
)
\mu(n)=-\mu(i)
μ(n)=−μ(i)
Code:
int prime[N],mu[N],vis[N],n,c;
void get_mu(){
mu[1]=1;
for(int i=2;i<N;i++){
if(vis[i]==0){
prime[c++]=i;
mu[i]=-1;
}
for(int j=0;1LL*prime[j]*i<N;j++){
vis[i*prime[j]]=1;
if(i%prime[j]==0){
mu[i*prime[j]]=0;
break;
}
mu[i*prime[j]]=-mu[i];
}
}
}
在了解莫比乌斯函数之后,那么我们就有必要深入了解有关莫比乌斯反演相关的数论知识…
又忙又想摆烂,真是没救了