2019 ICPC 银川区域赛 D 题解

D. Easy Problem

题意:

给定 \(n, m, d, k\),求所有满足 \(1 \le a_i \le m\) 且 \(\gcd(a_1,\dots,a_n)=d\) 的序列 \((a_1,\dots,a_n)\) 的 \((\prod_{i=1}^n a_i)^k\) 之和,对 \(59964251\) 取模。其中 \(n\) 以字符串形式给出(长度可达 \(10^5\)),\(m, d \le 10^5\),\(k \le 10^9\),\(T \le 20\)。

思路:

\(\gcd(a_1,\dots,a_n)=d\)
令 \(b_i=a_i\cdot d\),则 \(b_i\) 满足 \(1 \le b_i \le \lfloor \frac{m}{d} \rfloor\)
设题目的答案为 \(T(n, m, d, k)\),则 \(T(n, m, d, k)=T(n, \lfloor \frac{m}{d} \rfloor, 1, k)\cdot d^{nk}\)
\(\displaystyle T(n, m, 1, k)=\sum_{1\le a_i\le m}[\gcd(a_1,\dots,a_n)=1](\prod_{i=1}^n a_i)^k=\sum_{d=1}^{m}\mu(d)\sum_{1\le a_i\le \lfloor \frac{m}{d} \rfloor}(\prod_{i=1}^n a_i)^k\)
\(\displaystyle =\sum_{d=1}^{m}\mu(d)(\sum_{x=1}^{\lfloor \frac{m}{d} \rfloor} x^k)^n\)

发现 \(n\) 只出现在指数部分,考虑欧拉定理。
由于 \(59964251\) 不是质数,考虑扩展欧拉定理。

代码

点击查看代码
#include <bits/stdc++.h>
#define int long long
#define ll long long
#define ull unsigned long long
#define double long double
#define PII pair<int,int>
#define endl '\n'
using namespace std;
mt19937_64 rng(time(0));

const int N = 1e6 + 100, M = 2e3 + 10;
const int mod = 59964251, phi = 59870352;
const double EPS = 1e-8;

int mu[N], p[N], smu[N];
bool flg[N];
int tot = 0;
void getMu(int n) {
	mu[1] = 1;
	for (int i = 2; i <= n; ++i) {
		if (!flg[i]) p[++tot] = i, mu[i] = -1;
		for (int j = 1; j <= tot && i * p[j] <= n; ++j) {
			flg[i * p[j]] = 1;
			if (i % p[j] == 0) {
				mu[i * p[j]] = 0;
				break;
			}
			mu[i * p[j]] = -mu[i];
		}
	}
//	for(int i=2;i<=n;i++){
//		mu[i]+=mu[i-1];
//	}
}
ll qpow(ll x,ll n){
	ll ans=1;
	while(n){
		if(n&1){
			ans*=x;
			ans%=mod;
		}
		x*=x;
		x%=mod;
		n>>=1;
	}
	return ans;
}
int n=0, m, d, k;
int f=0;

int nqpow(int x){
	if(__gcd(x,mod)==1){
		return qpow(x,n);
	}else{
		if(f){
			return qpow(x,n+phi);
		}else{
			return qpow(x,n);
		}
	}
}

string s;
int a[N];

void solve() {
	n=f=0;
	cin >> s >> m >> d >> k;
	for(int i=0;i<s.length();i++){
		n*=10;
		n+=s[i]-'0';
		if(n>=phi){
			f=1;
		}
		n%=phi;
	}

	m/=d;
	for(int i=1;i<=m;i++){
		a[i]=qpow(i,k);
		a[i]+=a[i-1];
		a[i]%=mod;
	}
	int res=0;
	for(int l=1;l<=m;l++){
		res+=(mu[l]*qpow(nqpow(l),k)%mod)*nqpow(a[m/l])%mod;
		res%=mod;
	}

	res*=qpow(nqpow(d),k);
	res%=mod;
	cout<<(res+mod)%mod<<endl;

}


signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	int t = 1;
	cin >> t;
	getMu(1e6);
	while (t--) {
		solve();
	}

	return 0;
}
posted @ 2026-09-26 17:26  ptlks  阅读(20)  评论(0)    收藏  举报