LOJ6053 简单的函数

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

LOJ6053 简单的函数

题目大意

有一个函数 f ( x ) f(x) f(x)满足以下性质

  • f ( 1 ) = 1 f(1)=1 f(1)=1
  • f ( p c ) = p ⊕ c f(p^c)=p \oplus c f(pc)=pc p p p为质数 ⊕ \oplus 表示异或
  • f ( a b ) = f ( a ) f ( b ) f(ab)=f(a)f(b) f(ab)=f(a)f(b) a a a b b b互质

∑ i = 1 n f ( i ) \sum\limits_{i=1}^nf(i) i=1nf(i) ( 1 0 9 + 7 ) (10^9+7) (109+7)取模的结果其中 1 ≤ n ≤ 1 0 10 1\leq n\leq 10^{10} 1n1010


题解

前置知识min25筛

观察函数 f ( x ) f(x) f(x) f ( x ) f(x) f(x)在质数和质数的幂的位置比较好求我们考虑使用min25筛。

x x x为奇质数时 f ( x ) = x ⊕ 1 = x − 1 f(x)=x \oplus 1=x-1 f(x)=x1=x1。当 x x x为偶质数时 f ( x ) = x ⊕ 1 = x + 1 f(x)=x \oplus 1=x+1 f(x)=x1=x+1。令 p ( x ) = x − 1 p(x)=x-1 p(x)=x1 p p p函数代替 f f f函数然后将 p p p函数分为 f 1 ( x ) = x f_1(x)=x f1(x)=x f 2 ( x ) = 1 f_2(x)=1 f2(x)=1两个完全积性函数来求min25筛中的 g g g函数最后再用 f f f函数的性质来求min25筛中的 S S S函数。对于 p p p f f f x = 2 x=2 x=2处的差在最后加上即可。

为什么可以这样呢由函数 S ( n , i ) S(n,i) S(n,i)的递推式 f ( 2 ) f(2) f(2)的值改变只会影响 S S S的递推式中含有 g g g函数的部分。因为答案为 S ( n , 0 ) + 1 S(n,0)+1 S(n,0)+1而只有 i = 0 i=0 i=0时才会涉及到 f ( 2 ) f(2) f(2)的值 i ≠ 0 i\neq 0 i=0时两个 g g g函数相减将 f ( 2 ) f(2) f(2)的部分抵消了所以将 f f f改为 p p p在求答案的情况下只会影响一次也就是答案减少了 f ( 2 ) − g ( 2 ) = 3 − 1 = 2 f(2)-g(2)=3-1=2 f(2)g(2)=31=2在最后加上即可。

min25筛中函数 S S S的递推式

S ( n , i ) = g ( n , ∣ p r ( n ) ∣ ) − g ( p r i , ∣ p r ( n ) ∣ ) + ∑ j > i ∑ p r j k ≤ n f ( p r j k ) × ( S ( ⌊ n p r j k ⌋ , j ) + [ k > 1 ] ) S(n,i)=g(n,|pr(n)|)-g(pr_i,|pr(n)|)+\sum\limits_{j>i}\sum\limits_{pr_j^k\leq n}f(pr_j^k)\times (S(\lfloor\dfrac{n}{pr_j^k}\rfloor,j)+[k>1]) S(n,i)=g(n,pr(n))g(pri,pr(n))+j>iprjknf(prjk)×(S(⌊prjkn,j)+[k>1])

code

#include<bits/stdc++.h>
using namespace std;
const int N=200005;
const long long mod=1000000007;
int p1,vt,z[N+5],pr[N+5];
long long n,x,v[N+5],f[2][N+5],s1[N+5],s2[N+5],g1[N+5],g2[N+5];
void dd(){
	for(int i=2;i<=N;i++){
		if(!z[i]){
			pr[++p1]=i;
			s1[p1]=(s1[p1-1]+i)%mod;
			s2[p1]=p1;
		}
		for(int j=1;j<=p1&&i*pr[j]<=N;j++){
			z[i*pr[j]]=1;
			if(i%pr[j]==0) break;
		}
	}
}
void init(){
	x=sqrt(n)+1;
	dd();
	for(long long l=1,r;l<=n;l=r+1){
		r=n/(n/l);
		v[++vt]=n/l;
		if(n/l<=x) f[0][n/l]=vt;
		else f[1][l]=vt;
		long long t=(n/l)%mod;
		g1[vt]=(t*(t+1)/2%mod-1+mod)%mod;
		g2[vt]=(t-1+mod)%mod;
	}
	long long w;
	for(int i=1;i<=p1;i++){
		w=1ll*pr[i]*pr[i];
		long long t;
		for(int j=1;j<=vt&&w<=v[j];j++){
			t=v[j]/pr[i];
			if(t<=x) t=f[0][t];
			else t=f[1][n/t];
			g1[j]=(g1[j]-1ll*pr[i]*(g1[t]-s1[i-1])%mod+mod)%mod;
			g2[j]=(g2[j]-1ll*(g2[t]-s2[i-1])%mod+mod)%mod;
		}
	}
	
}
long long S(long long p,int q){
	if(pr[q]>=p) return 0;
	long long td=(p<=x?f[0][p]:f[1][n/p]);
	long long re=((g1[td]-g2[td]-s1[q]+s2[q])%mod+mod)%mod;
	for(int j=q+1;j<=p1;j++){
		if(1ll*pr[j]*pr[j]>p) break;
		for(long long o=1,pq=pr[j],t;pq<=p;++o,pq=pq*pr[j]){
			t=pq%mod;
			re=(re+1ll*(pr[j]^o)%mod*(S(p/pq,j)%mod+(o>1))%mod)%mod;
		}
	}
	return re;
}
int main()
{
	scanf("%lld",&n);
	init();
	if(n==1) printf("1");
	else printf("%lld\n",(S(n,0)+3)%mod);
	return 0;
}
阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6