题意
给两个数n,k问对于一个长度为n,元素范围为 的数组a,有多少个a的总gcd为1,记这个值为 ,要求输出
数据范围
解法
(异或和sigma之间一般没有combo,所以一般不先考虑
的性质,而是先求出
)
首先列出
的式子:
然后莫比乌斯反演掉最后的式子
然后到了这里,我们可以在 的时间里单独求出一个 ,其中 是整除分块, 是快速幂,然后我们预处理幂次可以做到 ,但是还不够.
我们观察上面的式子,发现这个式子没有用到求的
是连续的这个特点,所以我们经一步考虑:
考虑枚举的一个
,它会在所有
中都产生贡献,而且它的贡献形式是成段变化的.
所以考虑枚举每个d,把它造成的变化直接算到整个b数组里,可以发现这是一个差分.
然后复杂度是
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e6+5;
const int mod=1e9+7;
inline int read(){
char c=getchar();int t=0,f=1;
while((!isdigit(c))&&(c!=EOF)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)&&(c!=EOF)){t=(t<<3)+(t<<1)+(c^48);c=getchar();}
return t*f;
}
int n,k;
int mu[maxn],p[maxn],cnt,vis[maxn];
void get(){
mu[1]=1;
for(int i=2;i<=k;i++){
if(!vis[i]){
p[++cnt]=i;mu[i]=-1;
}
for(int j=1;j<=cnt&&1ll*i*p[j]<=k;j++){
vis[i*p[j]]=1;mu[i*p[j]]=mu[i]*mu[p[j]];
if(i%p[j]==0){
mu[i*p[j]]=0;break;
}
}
}
}
inline int ksm(int a,int b){
int ans=1;
while(b){
if(b&1)ans=1ll*ans*a%mod;
a=1ll*a*a%mod;b>>=1;
}
return ans;
}
int pw[maxn],b[maxn*2];
int main(){
n=read(),k=read();
for(int i=1;i<=k;i++)pw[i]=ksm(i,n);
get();
for(int x=1;x<=k;x++){
for(int i=1;i*x<=k;i++){
b[i*x]=(b[i*x]+1ll*pw[i]*(mod+mu[x])%mod)%mod;
b[i*x]=(b[i*x]-1ll*pw[i-1]*(mod+mu[x])%mod)%mod;
if(b[i*x]<0)b[i*x]+=mod;
}
}
int ans=0;
for(int i=1;i<=k;i++){
b[i]=(b[i]+b[i-1])%mod;
// printf("%d\n",b[i]);
ans=(ans+(b[i]^i)%mod)%mod;
}
printf("%d\n",ans);
return 0;
}