codeforces 915G

题目链接

题意

给两个数n,k问对于一个长度为n,元素范围为 1 k 1到k 的数组a,有多少个a的总gcd为1,记这个值为 b i b_i ,要求输出 i = 1 k ( b i   x o r   i ) \sum_{i=1}^k(b_i ~xor ~i)

数据范围

n , k 2 e 6 n,k\le 2e6

解法

(异或和sigma之间一般没有combo,所以一般不先考虑 b i   x o r   i b_i~xor~i 的性质,而是先求出 b i b_i )
首先列出 b b 的式子:

b m = a 1 = 1 m . . . a k = 1 m [ ( g c d i = 1 k a i ) = 1 ] b_m=\sum_{a_1=1}^m...\sum_{a_k=1}^m[({gcd_{i=1}^k}a_i)=1]
然后莫比乌斯反演掉最后的式子
b m = a 1 = 1 m . . . a k = 1 m d g c d i = 1 k a i μ ( d ) b_m=\sum_{a_1=1}^m...\sum_{a_k=1}^m\sum_{d|{gcd_{i=1}^k}a_i}\mu(d)
b m = d = 1 m μ ( d ) m d k b_m=\sum_{d=1}^m \mu(d)\lfloor \frac{m}{d} \rfloor^k

然后到了这里,我们可以在 O ( n l o g n ) O(\sqrt{n}logn) 的时间里单独求出一个 b i b_i ,其中 n \sqrt{n} 是整除分块, l o g n logn 是快速幂,然后我们预处理幂次可以做到 O ( n n ) O(n\sqrt{n}) ,但是还不够.

我们观察上面的式子,发现这个式子没有用到求的 b i b_i 是连续的这个特点,所以我们经一步考虑:
考虑枚举的一个 d d ,它会在所有 m d m\ge d 中都产生贡献,而且它的贡献形式是成段变化的.
所以考虑枚举每个d,把它造成的变化直接算到整个b数组里,可以发现这是一个差分.
然后复杂度是 d = 1 n n / d , O ( n l o g n ) \sum _{d=1}^n n/d,是O(nlogn)

#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;
}

发布了61 篇原创文章 · 获赞 1 · 访问量 976

猜你喜欢

转载自blog.csdn.net/wmhtxdy/article/details/103909732
今日推荐