HDU多校第6场1007 A Very Easy Math Problem

Problem Description

在这里插入图片描述

Input

在这里插入图片描述

Output

在这里插入图片描述

Sample Input

在这里插入图片描述

Sample Output

在这里插入图片描述
Source
2020 Multi-University Training Contest 6
在这里插入图片描述 得到上式后我们可以对这三项进行预处理 u ( d ) 2 d k x + 1 u ( d ) p k x S u(d)^2d^{kx+1} 、u(d)p^{kx}、S
然后我们再进行两次整除分块,求得ans。

#include<bits/stdc++.h>
#define db double
#define ll long long
#define inf 0x3f3f3f3f
#define ms(x,a) memset(x,a,sizeof(x))
using namespace std;
const int maxn = 2e5 + 10;
const ll mod = 1e9 + 7;
const ll mod1 = 1e9 + 6;
ll k,x,n;

ll qpow(ll x,ll n){
	ll res = 1;
	while(n){
		if(n & 1)res = res * x % mod;
		x = x * x % mod;
		n >>= 1;
	}
	return res;   
}


bool v[maxn];
int cnt;
ll p[maxn],mob[maxn],sm[maxn],s1[maxn],s2[maxn];

void getmob(){
	ms(v,0);
	ms(p,0);
	ms(mob,0);
	ms(sm,0);
	cnt = 0;
	mob[1] = v[1] = 1;
    for(int i = 2;i < maxn;i++){
        if(!v[i]){
            p[++cnt] = i;
            mob[i] = -1;
        }
        for(int j = 1;j <= cnt && i * p[j] <= maxn;j++){
            v[i * p[j]] = 1;
            if(i % p[j] == 0){
                mob[i * p[j]] = 0;
                break;
            }
            else{
                mob[i * p[j]] = -mob[i];
            }
        }
    }
	for(int i = 1;i < maxn;i++){
		sm[i] = (sm[i - 1] + qpow(i,k)) % mod;
	}
	for(int i = 1;i < maxn;i++){
		sm[i] = qpow(sm[i],x);
		s1[i] = (s1[i - 1] + qpow(i,(x * k + 1) % mod1 + mod1) * mob[i] * mob[i] % mod) % mod;
		s2[i] = ((s2[i - 1] + qpow(i,x * k % mod1 + mod1) * mob[i] % mod) % mod + mod) % mod;
	}
}

unordered_map<ll,ll>mp;

ll calc1(ll x){
	if(mp[x])return mp[x];
	ll res = 0;
	for(ll l = 1,r;l <= x;l = r + 1){
		r = x / (x / l);
		res = ((res + (s2[r] - s2[l - 1]) * sm[x / l]) % mod + mod) % mod;
	}
	return mp[x] = res;
}

ll calc2(ll x){
	ll res = 0;
	for(ll l = 1,r;l <= x;l = r + 1){
		r = x / (x / l);
		res = ((res + (s1[r] - s1[l - 1]) * calc1(x / l)) % mod + mod) % mod;
	}
	return res;
}

void solve(){
	scanf("%lld",&n);
	printf("%lld\n",calc2(n));
}

int main() {
//    ios::sync_with_stdio(false);
//    cin.tie(0);
	int t;
	scanf("%d%lld%lld",&t,&k,&x);
	getmob();
	for(int ca = 1; ca <= t; ca++) {
		solve();
	}
	return 0;
}

//Dawn_Exile




猜你喜欢

转载自blog.csdn.net/weixin_43873569/article/details/107847823