codeforces 1436 F

题目链接:https://codeforces.com/contest/1436/problem/F

题目大意:

一个多重集 (S),有 (m) 种不同的数,第 (i) 种数为 (a_i),有 (freq_i) 个。

求满足如下条件的和式 (∑x∈A∑y∈Bxy∑x∈A∑y∈Bxy) 的值:

[B⊂A ]

[|B|=|A|−1|B|=|A|−1 ]

[gcdx∈A{x}=1 ]

注意,其中 (A,B) 也为多重集。

涉及 (gcd) 的式子一般可以用套路莫比乌斯反演

(f(i))(gcd)(i) 时的答案
很难直接算
于是另 (g(i) = sum_{i mid d} mu(frac{d}{i})f(d))

答案就是 $$f(1) = sum_{i = 1}^n mu(i)g(i)$$

考虑计算 (g(i)), 将所有 (i) 的倍数找出来放到一个集合中,计算这个集合的答案
设该集合大小为 (k), 考虑每一对 (a_i * a_j) 的贡献,

当x和y是同一个数的时候,贡献是 (x^2(k−1)2^{k-2}freq[x])

当x和y数值相同但不是同一个数的时候,贡献是 (x^2[(k−2)2^{k-3}+2^{k−2}]freq[x](freq[x]−1))

当x不等于y的时候,贡献是 (xy[(k−2)2^{k-3}+2^{k−2}]freq[x]freq[y])

(上述公式是考虑 (B) 是由 (A) 删去了哪个数得出的)

(x, y) 不相等的情况还是无法直接枚举,发现 (y) 一定是 (i) 的倍数,所以推一下式子用前缀和优化一下即可

注意: 取模一定要仔细

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> P;

const int maxn = 100010;
const ll M = 998244353;
const int N = 100000;

int n, m;
ll ans;
ll a[maxn], c[maxn];
int is[maxn], prime[maxn], mu[maxn], cnt = 0;

ll qsm(ll i, ll po){
	ll res = 1;
	while(po){
		if(po & 1) res = 1ll * res * i % M;
		po >>= 1;
		i = 1ll * i * i % M;
	}
	return res;
}

vector<P> v;

ll read(){ ll s = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * f; }

int main(){
	ll inv = qsm(2, M - 2);
	
	m = read();
	for(int i = 1 ; i <= m ; ++i) {
		a[i] = read(), c[a[i]] = read();
	}
	
	mu[1] = 1, is[1] = 1;
	for(int i = 2 ; i <= N ; ++i){
		if(!is[i]){
			prime[++cnt] = i;
			mu[i] = -1;
		}
		for(int j = 1 ; j <= cnt && i * prime[j] <= N ; ++j){
			is[i * prime[j]] = 1;
			if(i % prime[j] == 0){
				mu[i * prime[j]] = 0;
				break;
			} else{
				mu[i * prime[j]] = -mu[i];
			}
		}
	}
	
	for(int i = 1 ; i <= N ; ++i){
		v.clear();
		ll s1 = 0, s2 = 0, s3 = 0, s = 0;
		ll K = 0; 
		
		for(int j = i ; j <= N ; j += i){ // 统计集合大小 
			if(!c[j]) continue;
			K += c[j];
			s = (s + 1ll * j * c[j] % M) % M;
			v.emplace_back(j, c[j]);
		}
		
		for(auto j : v){
			ll tt = 0;
			if(K >= 2){
				tt = qsm(2, K - 2);
				s1 = (s1 + 1ll * j.first * j.first % M * ((K - 1) % M) % M * tt % M * j.second % M) % M;
			}
			if(K >= 3){
				tt = (tt + 1LL * (K - 2) % M * tt % M * inv % M) % M;
			}
		    s2 = (s2 + 1LL * j.first * j.first % M * tt % M * j.second % M * (j.second - 1) % M) % M;
            s3 = (s3 + 1LL * j.first * j.second % M * tt % M * (s - 1LL * j.first * j.second % M) % M) % M;
		}
		
		ans = ((ans + 1ll * mu[i] * ((s1 + s2 + s3) % M)) % M + M) % M;
	}
	
	printf("%lld
", ans);
	
	return 0;
}
原文地址:https://www.cnblogs.com/tuchen/p/14285524.html