The Preliminary Contest for ICPC Asia Nanjing 2019 E K Sum

6 篇文章 1 订阅

The Preliminary Contest for ICPC Asia Nanjing 2019

E题 K Sum

题意:定义
f n ( k ) = ∑ l 1 = 1 n ∑ l 2 = 1 n … ∑ l k = 1 n ( g c d ( l 1 , l 2 , … , l k ) ) 2 f_n(k)=\sum\limits_{l_1=1}^{n}\sum\limits_{l_2=1}^{n}…\sum\limits_{l_k=1}^{n}(gcd(l_1,l_2,…,l_k))^2 fn(k)=l1=1nl2=1nlk=1n(gcd(l1,l2,,lk))2
计算: ∑ i = 2 k f n ( i )   m o d u l o   1 0 9 + 7 , 1 ≤ n ≤ 1 0 9 , 2 ≤ k ≤ 1 0 1 0 5 \sum\limits_{i=2}^{k}f_n(i)\ modulo\ 10^9+7,1\leq n\leq 10^9,2\leq k\leq10^{10^5} i=2kfn(i) modulo 109+7,1n109,2k10105
题解:
f n ( i ) = ∑ l 1 = 1 n ∑ l 2 = 1 n … ∑ l i = 1 n ( g c d ( l 1 , l 2 , … , l i ) ) 2 f_n(i)=\sum\limits_{l_1=1}^{n}\sum\limits_{l_2=1}^{n}…\sum\limits_{l_i=1}^{n}(gcd(l_1,l_2,…,l_i))^2 fn(i)=l1=1nl2=1nli=1n(gcd(l1,l2,,li))2
= ∑ d = 1 n d 2 ∑ l 1 = 1 n ∑ l 2 = 1 n … ∑ l i = 1 n [ g c d ( l 1 , l 2 , … , l i ) = d ] =\sum\limits_{d=1}^nd^2\sum\limits_{l_1=1}^{n}\sum\limits_{l_2=1}^{n}…\sum\limits_{l_i=1}^{n}[gcd(l_1,l_2,…,l_i)=d] =d=1nd2l1=1nl2=1nli=1n[gcd(l1,l2,,li)=d]
= ∑ d = 1 n d 2 ∑ l 1 = 1 n d ∑ l 2 = 1 n d … ∑ l i = 1 n d [ g c d ( l 1 , l 2 , … , l i ) = 1 ] =\sum\limits_{d=1}^nd^2\sum\limits_{l_1=1}^{\frac{n}{d}}\sum\limits_{l_2=1}^{\frac{n}{d}}…\sum\limits_{l_i=1}^{\frac{n}{d}}[gcd(l_1,l_2,…,l_i)=1] =d=1nd2l1=1dnl2=1dnli=1dn[gcd(l1,l2,,li)=1]
= ∑ d = 1 n d 2 ∑ l 1 = 1 n d ∑ l 2 = 1 n d … ∑ l i = 1 n d ∑ t ∣ g c d ( l 1 , l 2 , … , l i ) μ ( t ) =\sum\limits_{d=1}^nd^2\sum\limits_{l_1=1}^{\frac{n}{d}}\sum\limits_{l_2=1}^{\frac{n}{d}}…\sum\limits_{l_i=1}^{\frac{n}{d}}\sum\limits_{t|gcd(l_1,l_2,…,l_i)}\mu(t) =d=1nd2l1=1dnl2=1dnli=1dntgcd(l1,l2,,li)μ(t)
= ∑ d = 1 n d 2 ∑ t = 1 n d μ ( t ) ⌊ n t d ⌋ i =\sum\limits_{d=1}^nd^2\sum\limits_{t=1}^{\frac{n}{d}} \mu(t){\lfloor \frac{n}{td}\rfloor}^i =d=1nd2t=1dnμ(t)tdni
= ∑ T = 1 n ⌊ n T ⌋ i ∑ d ∣ T d 2 μ ( T d ) =\sum\limits_{T=1}^n{\lfloor \frac{n}{T}\rfloor}^i\sum\limits_{d|T}d^2\mu(\frac{T}{d}) =T=1nTnidTd2μ(dT)
∑ i = 2 k f n ( i ) = ∑ i = 2 k ∑ T = 1 n ⌊ n T ⌋ i ∑ d ∣ T d 2 μ ( T d ) \sum\limits_{i=2}^kf_n(i)=\sum\limits_{i=2}^k\sum\limits_{T=1}^n{\lfloor \frac{n}{T}\rfloor}^i\sum\limits_{d|T}d^2\mu(\frac{T}{d}) i=2kfn(i)=i=2kT=1nTnidTd2μ(dT)
= ∑ T = 1 n ∑ i = 2 k ⌊ n T ⌋ i ∑ d ∣ T d 2 μ ( T d ) =\sum\limits_{T=1}^n\sum\limits_{i=2}^k{\lfloor \frac{n}{T}\rfloor}^i\sum\limits_{d|T}d^2\mu(\frac{T}{d}) =T=1ni=2kTnidTd2μ(dT)
f = ∑ d ∣ T d 2 μ ( T d ) = i d 2 ∗ μ , g = 1 , h = f ∗ g = i d 2 f=\sum\limits_{d|T}d^2\mu(\frac{T}{d})=id^2*\mu,g=1,h=f*g=id^2 f=dTd2μ(dT)=id2μg=1,h=fg=id2
由于杜教筛公式:
g ( 1 ) S ( n ) = ∑ i = 1 n h ( i ) − ∑ d = 2 n g ( d ) S ( ⌊ n d ⌋ ) g(1)S(n)=\sum\limits_{i=1}^{n}h(i)-\sum\limits_{d=2}^{n}g(d)S(\lfloor\frac{n}{d}\rfloor) g(1)S(n)=i=1nh(i)d=2ng(d)S(dn)
可以构造解决这个前缀和。
∑ i = 2 k ⌊ n T ⌋ i \sum\limits_{i=2}^k{\lfloor \frac{n}{T}\rfloor}^i i=2kTni,记 q = ⌊ n T ⌋ , ∑ i = 2 k ⌊ n T ⌋ i = q 2 ( q k − 1 − 1 ) q − 1 q={\lfloor \frac{n}{T}\rfloor},\sum\limits_{i=2}^k{\lfloor \frac{n}{T}\rfloor}^i=\frac{q^2(q^{k-1}-1)}{q-1} q=Tn,i=2kTni=q1q2(qk11)
然后按照 ⌊ n T ⌋ {\lfloor \frac{n}{T}\rfloor} Tn整数分块就行了
对于 f = i d 2 ∗ μ f=id^2*\mu f=id2μ,需要预处理 1 e 6 1e6 1e6之内的前缀和,
两个积性函数卷积的线性筛法:

vis[1] = low[1] = 1; H[1] = 初始化 
for(int i = 2; i <= N; i++) {
    if(!vis[i]) prime[++tot] = i, mu[i] = -1, H[i] = 质数的情况, low[i] = i;
    for(int j = 1; j <= tot && i * prime[j] <= N; j++) {
        vis[i * prime[j]] = 1;
        if(!(i % prime[j])) {
            low[i * prime[j]] = (low[i] * prime[j]); 
            if(low[i] == i) H[i * prime[j]] = 特殊判断;
            else H[i * prime[j]] = H[i / low[i]] * H[prime[j] * low[i]];
            break;
        } 
        H[i * prime[j]] = H[i] * H[prime[j]];
        low[i * prime[j]] = prime[j];
    }
}
#include<cstdio>
#include<map>
#include<cstring>
#define ll long long
using namespace std;
const int mod = 1e9+7;
const int maxn = 1e6+10;
bool vis[maxn];
map<int ,ll> mp;
ll low[maxn],H[maxn],sum[maxn];
int prime[maxn];
int tot,T;
char k[100010];
ll inv6;
ll f_g_sum(int n){
	return (ll)n%mod*(n+1)%mod*(2*n+1)%mod*inv6%mod;
}
ll g_sum(int n){
	return n%mod;
}
void f_sum(int n){
	tot=0;
	vis[1]=low[1]=1;
	H[1]=1;
	for(int i=2;i<=n;i++){
		if(!vis[i]){
			prime[++tot]=i;
			H[i]=(i*i-1)%mod;
			low[i]=i;
		}
		for(int j=1;j<=tot&&(ll)i*prime[j]<=n;j++){
			vis[i*prime[j]]=1;
			if(!(i%prime[j])){
				low[i*prime[j]]=(low[i]*prime[j]);
				if(low[i]==i)H[i*prime[j]]=(ll)prime[j]*prime[j]*H[i]%mod;
				else H[i*prime[j]]=H[i/low[i]]*H[prime[j]*low[i]];
				break;
			}
			H[i*prime[j]]=H[i]*H[prime[j]];
			low[i*prime[j]]=prime[j];
		}
	}
	sum[0]=0;
	for(int i=1;i<=n;i++)
		sum[i]=(sum[i-1]+H[i])%mod;
}
ll qpow(ll a,ll b){
	ll res=1;
	while(b){
		if(b&1)res=res*a%mod;
		a=a*a%mod;
		b>>=1;
	}
	return res;
}
ll GetSum(int n){
	if(n<=1000000)return sum[n];
	if(mp[n]!=0)return mp[n];
	ll ans = f_g_sum(n)%mod;
	for(ll l = 2, r; l <= n; l = r + 1) {
		r = (n / (n / l)); 
		ans = (ans - (g_sum(r) - g_sum(l - 1)) * GetSum(n / l) + mod)%mod;
	}
	mp[n]=ans;
	return ans; 
}
ll inv(int n){
	return qpow(n,mod-2);
}
int main(){
	int n,m,len;
	m=mod-1;
	inv6=qpow(6,mod-2);
	f_sum(1000000);
	scanf("%d",&T);
	while(T--){
		scanf("%d%s",&n,k);
		len=strlen(k);
		int pow=0,K=0;
		for(int i=0;i<len;i++){
			pow=(int)(((ll)pow*10+k[i]-'0')%m);
			K=(int)(((ll)K*10+k[i]-'0')%mod);
		}
		pow=(pow-1+m)%m;
		K=(K-1+mod)%mod;
		ll ans=0;
		for(int l=1,r;l<=n;l=r+1){
			r=n/(n/l);
			ll q=n/l;
			ll val;
			if(q!=1)
				val=q*q%mod*(qpow(q,pow)-1+mod)%mod*inv(q-1)%mod;
			else val=K;
			ans=(ans+(val*(GetSum(r)-GetSum(l-1)+mod)%mod)%mod)%mod;
		}
		printf("%lld\n",ans);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值