题目
狄利克雷前缀和
题解
n
=
p
1
k
1
p
2
k
2
.
.
.
p
m
k
m
a
=
p
1
b
1
p
2
b
2
.
.
.
p
m
b
m
∀
i
,
b
i
≤
k
i
g
(
n
)
=
∑
f
(
a
)
n=p_1^{k_1}p_2^{k_2}...p_m^{k_m}\\ a=p_1^{b_1}p_2^{b_2}...p_m^{b_m}\\ \forall i, b_i\leq k_i \\ g(n)=\sum f(a)
n=p1k1p2k2...pmkma=p1b1p2b2...pmbm∀i,bi≤kig(n)=∑f(a)
将任意一个数质因数分解,取每个质因数的次数,作为
m
m
m维数组
g
g
g就是求
m
m
m维前缀和
每次处理一维,用一维前缀和的方式累加
处理
m
m
m次就行
O
(
n
l
o
g
l
o
g
n
)
O(nloglogn)
O(nloglogn)似乎是均摊复杂度
#include<bits/stdc++.h>
#define uint unsigned int
using namespace std;
uint seed;
inline uint getnext(){
seed^=seed<<13;
seed^=seed>>17;
seed^=seed<<5;
return seed;
}
const int N=2e7+10,M=2e7;
int n;
uint a[N];
int z[N],p;
bool vis[N];
void Sieve()
{
for(int i=2;i<=n;i++)
{
if(!vis[i])z[++p]=i;
for(int j=1;j<=p&&i*z[j]<=n;j++)
{
vis[i*z[j]]=1;
if(i%z[j]==0)break;
}
}
}
int main()
{
cin>>n>>seed;
Sieve();
for(int i=1;i<=n;i++)a[i]=getnext();
for(int i=1;i<=p;i++)
for(int j=1;z[i]*j<=n;j++)
a[z[i]*j]+=a[j];
uint ans=0;
for(int i=1;i<=n;i++)ans^=a[i];
cout<<ans;
}