[ f ( x ) ] [f(x)] [f(x)] 表示艾弗森括号,若 f ( x ) f(x) f(x) 表达式为真,值为1,否则为0 μ ( x ) \mu(x) μ(x) 表示莫比乌斯函数 a ∣ b a|b a∣b 表示a整除b,即a是b的因子,b是a的倍数
题意
CF链接 给定函数 f ( n ) f(n) f(n),即质因子分解后,指数取模 2 2 2后的乘积 f ( n ) = ∏ i p i s i % 2 f(n)=\prod_{i}p_i^{s_i\%2} f(n)=i∏pisi%2 给定长度为 n n n 的序列 b [ n ] b[n] b[n],求 ∑ 1 ≤ i < j ≤ n f ( b i × b j ) ( m o d 1 e 9 + 7 ) \sum_{1\le i<j\le n}f(b_i \times b_j) \pmod{1e9+7} 1≤i<j≤n∑f(bi×bj)(mod1e9+7)
1 ≤ n ≤ 2 ⋅ 1 0 5 1\le n\le 2\cdot 10^5 1≤n≤2⋅105 1 ≤ b i ≤ 2 ⋅ 1 0 5 1\le b_i\le 2\cdot 10^5 1≤bi≤2⋅105
思路
首先需要推一下 f ( a × b ) f(a\times b) f(a×b) 函数的性质 f ( a × b ) = f ( ∏ i p i s i × ∏ j p j s j ) = f ( ∏ k p k s k i + s k j ) = ∏ k p k ( s k i + s k j ) % 2 = ∏ k l c m ( p k s k i % 2 , p k s k j % 2 ) g c d ( p k s k i % 2 , p k s k j % 2 ) = ∏ k l c m ( f ( p k s k i ) , f ( p k s k j ) ) g c d ( f ( p k s k i ) , f ( p k s k j ) ) = l c m ( f ( a ) , f ( b ) ) g c d ( f ( a ) , f ( b ) ) = f ( a ) × f ( b ) ( g c d ( f ( a ) , f ( b ) ) ) 2 \begin{aligned} f(a\times b)&=f(\prod_i p_i^{s_i} \times \prod_j p_j^{s_j})\\ &=f(\prod_k p_k^{s_{k_i}+s_{k_j}})\\ &=\prod_k p_k^{(s_{k_i}+s_{k_j})\%2}\\ &=\prod_k\frac{lcm(p_k^{s_{k_i}\%2},p_k^{s_{k_j}\%2})}{gcd(p_k^{s_{k_i}\%2},p_k^{s_{k_j}\%2})}\\ &=\prod_k \frac{lcm(f(p_k^{s_{k_i}}),f(p_k^{s_{k_j}}))}{gcd(f(p_k^{s_{k_i}}),f(p_k^{s_{k_j}}))}\\ &=\frac{lcm(f(a),f(b))}{gcd(f(a),f(b))}\\ &=\frac{f(a)\times f(b)}{\Big(gcd(f(a),f(b))\Big)^2} \end{aligned} f(a×b)=f(i∏pisi×j∏pjsj)=f(k∏pkski+skj)=k∏pk(ski+skj)%2=k∏gcd(pkski%2,pkskj%2)lcm(pkski%2,pkskj%2)=k∏gcd(f(pkski),f(pkskj))lcm(f(pkski),f(pkskj))=gcd(f(a),f(b))lcm(f(a),f(b))=(gcd(f(a),f(b)))2f(a)×f(b)
主要考虑到单独考虑每个质因子,然后考虑指数取模2后运算有点类似于异或运算,所以可以改成 lcm 除以 gcd,然后再用 f f f 函数反替换。
那么答案需要求的就是(以下表述省略取模运算): I = ∑ 1 ≤ i < j ≤ n f ( b i × b j ) = ∑ 1 ≤ i < j ≤ n f ( b i ) × f ( b j ) g c d ( f ( b i ) , f ( b j ) ) 2 = ∑ d = 1 ∑ 1 ≤ i < j ≤ n [ g c d ( f ( b i ) , f ( b j ) ) = d ] f ( b i ) × f ( b j ) d 2 = ∑ d = 1 1 2 ( ∑ i = 1 ∑ j = 1 [ g c d ( f ( b i ) , f ( b j ) ) = d ] f ( b i ) × f ( b j ) d 2 − ∑ p [ g c d ( f ( b p ) , f ( b p ) ) = d ] f ( b p ) 2 d 2 ) = 1 2 ∑ d = 1 ( ∑ i = 1 ∑ j = 1 [ g c d ( f ( b i ) , f ( b j ) ) = d ] f ( b i ) × f ( b j ) d 2 ) − 1 2 ∑ p ∑ d = 1 [ f ( b p ) = d ] f ( b p ) 2 d 2 = 1 2 ∑ d = 1 g ( d ) d 2 − n 2 \begin{aligned} I&=\sum_{1\le i<j\le n}f(b_i \times b_j)\\ &=\sum_{1\le i<j\le n} \frac{f(b_i)\times f(b_j)}{gcd(f(b_i),f(b_j))^2}\\ &=\sum_{d=1}\sum_{1\le i<j\le n} \Big[gcd(f(b_i),f(b_j))=d\Big]\frac{f(b_i)\times f(b_j)}{d^2}\\ &=\sum_{d=1}\frac{1}{2}\Big(\sum_{i=1}\sum_{j=1}\Big[gcd(f(b_i),f(b_j))=d\Big]\frac{f(b_i)\times f(b_j)}{d^2} - \sum_p[gcd(f(b_p),f(b_p))=d]\frac{f(b_p)^2}{d^2}\Big)\\ &=\frac{1}{2}\sum_{d=1}(\sum_{i=1}\sum_{j=1}\Big[gcd(f(b_i),f(b_j))=d\Big]\frac{f(b_i)\times f(b_j)}{d^2}) - \frac{1}{2}\sum_p\sum_{d=1}[f(b_p)=d]\frac{f(b_p)^2}{d^2}\\ &=\frac{1}{2}\sum_{d=1}\frac{g(d)}{d^2} -\frac{n}{2} \end{aligned} I=1≤i<j≤n∑f(bi×bj)=1≤i<j≤n∑gcd(f(bi),f(bj))2f(bi)×f(bj)=d=1∑1≤i<j≤n∑[gcd(f(bi),f(bj))=d]d2f(bi)×f(bj)=d=1∑21(i=1∑j=1∑[gcd(f(bi),f(bj))=d]d2f(bi)×f(bj)−p∑[gcd(f(bp),f(bp))=d]d2f(bp)2)=21d=1∑(i=1∑j=1∑[gcd(f(bi),f(bj))=d]d2f(bi)×f(bj))−21p∑d=1∑[f(bp)=d]d2f(bp)2=21d=1∑d2g(d)−2n
注意到,首先是式子替换,然后套路枚举 g c d = d gcd=d gcd=d,然后把 1 ≤ i < j ≤ n 1\le i<j\le n 1≤i<j≤n 拆成了 1 ≤ i , j ≤ n 1\le i,j\le n 1≤i,j≤n 的部分,为了方便后续的计算。 然后本质就是求上述的 g ( d ) g(d) g(d) 函数。 g ( d ) = ∑ i = 1 ∑ j = 1 [ g c d ( f ( b i ) , f ( b j ) ) = d ] f ( b i ) × f ( b j ) g(d)=\sum_{i=1}\sum_{j=1}\Big[gcd(f(b_i),f(b_j))=d\Big]f(b_i)\times f(b_j) g(d)=i=1∑j=1∑[gcd(f(bi),f(bj))=d]f(bi)×f(bj)
它不好算,我们看看它的和函数好不好算。 令 G ( n ) = ∑ n ∣ d g ( d ) G(n)=\sum_{n|d}g(d) G(n)=∑n∣dg(d)
继续计算 G ( n ) = ∑ n ∣ d ∑ i = 1 ∑ j = 1 [ g c d ( f ( b i ) , f ( b j ) ) = d ] f ( b i ) × f ( b j ) = ∑ i = 1 ∑ j = 1 ∑ n ∣ d [ g c d ( f ( b i ) , f ( b j ) ) = d ] f ( b i ) × f ( b j ) = ∑ i = 1 ∑ j = 1 ∑ n ∣ g c d ( f ( b i ) , f ( b j ) ) f ( b i ) × f ( b j ) = ∑ i = 1 ∑ j = 1 ∑ n ∣ f ( b i ) 且 n ∣ f ( b j ) f ( b i ) × f ( b j ) = ( ∑ i = 1 [ n ∣ b i ] f ( b i ) ) 2 \begin{aligned} G(n)&=\sum_{n|d}\sum_{i=1}\sum_{j=1}\Big[gcd(f(b_i),f(b_j))=d\Big]f(b_i)\times f(b_j)\\ &=\sum_{i=1}\sum_{j=1}\sum_{n|d}\Big[gcd(f(b_i),f(b_j))=d\Big]f(b_i)\times f(b_j)\\ &=\sum_{i=1}\sum_{j=1}\sum_{n|gcd(f(b_i),f(b_j))}f(b_i)\times f(b_j)\\ &=\sum_{i=1}\sum_{j=1}\sum_{n|f(b_i)且n|f(b_j)}f(b_i)\times f(b_j)\\ &=(\sum_{i=1}\Big[n|b_i\Big]f(b_i))^2 \end{aligned} G(n)=n∣d∑i=1∑j=1∑[gcd(f(bi),f(bj))=d]f(bi)×f(bj)=i=1∑j=1∑n∣d∑[gcd(f(bi),f(bj))=d]f(bi)×f(bj)=i=1∑j=1∑n∣gcd(f(bi),f(bj))∑f(bi)×f(bj)=i=1∑j=1∑n∣f(bi)且n∣f(bj)∑f(bi)×f(bj)=(i=1∑[n∣bi]f(bi))2
最后一行有些巧妙。对于都是 n n n 的倍数的所有数字 f ( b i ) f(b_i) f(bi) 都放到一个集合中,然后取每对两两乘积的和,相当于求他们的和的平方,即: ( ∑ i x i ) 2 = ∑ i ∑ j x i x j = ∑ i x i 2 + 2 ∑ i < j x i x j (\sum_i x_i)^2=\sum_i \sum_j x_ix_j=\sum_i x_i^2+2\sum_{i<j}x_ix_j (i∑xi)2=i∑j∑xixj=i∑xi2+2i<j∑xixj
而最后一行十分好计算,我们只需把 f ( x ) f(x) f(x) 存入桶中,可快速。
最后,直接反演即可 g ( n ) = ∑ n ∣ d μ ( d n ) G ( d ) g(n)=\sum_{n|d}\mu(\frac{d}{n})G(d) g(n)=n∣d∑μ(nd)G(d)
代码
求所有的 f ( n ) f(n) f(n) 复杂度为 2 e 5 × n \sqrt{2e5} \times n 2e5×n (可缩小,但没必要) 求所有的 G ( n ) G(n) G(n) 复杂度为 n log n n\log n nlogn 求所有的 g ( n ) g(n) g(n) 复杂度为 n log n n\log n nlogn 求所有的 μ ( n ) \mu(n) μ(n) 复杂度为 n n n,用欧拉筛
#include<bits/stdc++.h>#defineIOSios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
using namespace std;typedeflonglong ll;voidshow(){
std::cerr << endl;}template<typename T,typename... Args>voidshow(T x,Args... args){
std::cerr <<"[ "<< x <<" ] , ";show(args...);}constint MAX =2e5+50;constint MOD =1e9+7;constint INF =0x3f3f3f3f;const ll LINF =0x3f3f3f3f3f3f3f3f;constdouble EPS =1e-7;constdouble PI =acos(-1);
ll qpow(ll a,ll n){
/* */ll res =1LL;while(n){
if(n&1)res=res*a%MOD;a=a*a%MOD;n>>=1;}return res;}
ll qpow(ll a,ll n,ll p){
a%=p;ll res =1LL;while(n){
if(n&1)res=res*a%p;a=a*a%p;n>>=1;}return res;}
ll npow(ll a,ll n){
/* */ll res =1LL;while(n){
if(n&1)res=res*a;a=a*a;n>>=1;if(res<0||a<0)return0;}return res;}
ll inv(ll a){
/* */returnqpow(a,MOD-2);}
ll inv(ll a,ll p){
returnqpow(a,p-2,p);}
bool vis[MAX];int prime[MAX];int mu[MAX];int cnt;voidshai(int n){
mu[1]=1;for(int i =2;i <= n;++i){
if(!vis[i]){
prime[++cnt]= i;
mu[i]=-1;}for(int j =1;j <= cnt && i * prime[j]<= n;++j){
vis[i*prime[j]]=1;if(i % prime[j])mu[i*prime[j]]=-mu[i];else{
mu[i*prime[j]]=0;break;}}}}int bar[MAX];intf(int x){
int ans =1;for(int i =2;i * i <= x;++i){
if(x % i ==0){
int cnt =0;while(x % i ==0){
cnt++;
x /= i;}if(cnt&1)ans *= i;}}if(x >1)ans *= x;return ans;}
ll G[MAX],g[MAX];
ll iv2[MAX];voidinit(int n){
for(int i =1;i <= n;++i){
iv2[i]=inv(i);
iv2[i]=(iv2[i]* iv2[i])% MOD;}}voidcal_G(){
for(int n =1;n <=200000;++n){
for(int k =1;n * k <=200000;++k){
G[n]=(G[n]+ bar[n*k]* n % MOD * k % MOD)% MOD;}
G[n]= G[n]* G[n]% MOD;}}voidcal_g(){
for(int n =1;n <=200000;++n){
for(int k =1;n * k <=200000;++k){
int d = n * k;
g[n]=(g[n]+ mu[k]* G[d]% MOD + MOD)% MOD;}}}intmain(){
IOS;shai(200000);init(200000);int n;cin >> n;for(int i =1;i <= n;++i){
int x;cin >> x;
bar[f(x)]++;}cal_G();cal_g();
ll ans =0;for(int d =1;d <=200000;++d){
ans =(ans + g[d]* iv2[d]% MOD);}
ans =(ans - n + MOD)% MOD;
ans = ans *inv(2)% MOD;
cout << ans;return0;}