题解:CF915G Coprime Arrays
题意
我们称一个大小为 \(n\) 的数组 \(a\) 互质,当且仅当 \(\gcd(a_1,a_2,\cdots,a_n)=1\)。
给定 \(n,k\),对于每个 \(i\) \((1\le i\le k)\),你都需要确定这样的数组的个数——长度为 \(n\) 的互质数组 \(a\) ,满足对每个 \(j\) \((1\le j\le n)\),都有 \(1\le a_j\le i\)。
分析
我们设 \(f(x)\) 为 \(x\) 所对应的互质数组的个数。
按照题意,可以列出这样一个式子:
简单推一下式子:
因为 \(\mu*\mathbf{1}=\varepsilon\),即 \(\varepsilon(x)=\sum_{d|x}\mu(d)\) 所以有:
变换求值顺序,枚举 \(d\):
于是我们得到了一个 \(O(k\sqrt{k}+k\log n)\) 的做法。
在 \(n,k\leq2\times10^6\) 的规模下,无法通过本题。
有个显然的引理:
据此考虑差分:
根据上述引理,当且仅当 \(d|x\) 时 \(\left(\left\lfloor\frac{x}{d}\right\rfloor^n-\left\lfloor\frac{x-1}{d}\right\rfloor^n\right) \neq 0\),所以上式可以如下改写:
所以,我们可以枚举 \(d\),然后将所有满足 \(d|x\) 的 \(\Delta f(x)\) 加上 \(\mu(d)\left(\left\lfloor\frac{x}{d}\right\rfloor^n-\left\lfloor\frac{x-1}{d}\right\rfloor^n\right)\)。
通过前缀和统计答案。
时间复杂度 \(O(k\log n+k \log k)\)。
Code
#include<bits/stdc++.h>
using namespace std;
#define maxn 2000006
#define mod 1000000007
int mu[maxn];
bool vis[maxn];
vector<int> pri;
void init()
{
mu[1]=1;
for(int i=2;i<maxn;i++)
{
if(!vis[i]) mu[i]=-1, vis[i]=1, pri.emplace_back(i);
for(auto p:pri)
{
if(p*i>=maxn) break;
vis[p*i]=1;
if(i%p==0) break;
mu[i*p]=-mu[i];
}
}
}
int ksm(int64_t x, int l)
{
int64_t ret=1;
for(;l;l>>=1, x=x*x%mod)
if(l&1) ret=ret*x%mod;
return ret;
}
int lev[maxn], det[maxn];
int main()
{
int n, k;
cin>>n>>k;
init();
for(int i=1;i<=k;i++)
lev[i]=ksm(i, n);
for(int d=1;d<=k;d++)
for(int j=1;d*j<=k;j++)
det[d*j]=((det[d*j]+mu[d]*(mod+(lev[j]-lev[j-1])%mod)%mod)%mod+mod)%mod;
int ans=0, otp=0;
for(int i=1;i<=k;i++)
otp=(otp+(i^(ans=(ans+det[i])%mod)))%mod;
cout<<otp%mod;
}

浙公网安备 33010602011771号