51nod1188最大公约数之和V2(欧拉函数+线性筛)

本文详细解析了51nod1188题目的解题思路,通过数学推导,将原问题转化为求解两个积性函数的Dirichlet卷积,并给出了线性筛和Dirichlet卷积两种解法的代码实现。

题目:51nod1188.
题目大意:给定一个数 n n n,求:
∑ i = 1 n ∑ j = i + 1 n g c d ( i , j ) \sum_{i=1}^{n}\sum_{j=i+1}^{n}gcd(i,j) i=1nj=i+1ngcd(i,j)

1 ≤ n ≤ 5 ∗ 1 0 6 1\leq n\leq 5*10^6 1n5106,数据组数 ≤ 5 ∗ 1 0 4 \leq 5*10^4 5104.

直接推导下去:
∑ i = 1 n ∑ j = i + 1 n g c d ( i , j ) = ∑ i = 1 n ∑ j = 1 i g c d ( i , j ) − ∑ i = 1 n i = ∑ i = 1 n ∑ j = 1 i g c d ( i , j ) − n ( n + 1 ) 2 \sum_{i=1}^{n}\sum_{j=i+1}^{n}gcd(i,j)\\ =\sum_{i=1}^{n}\sum_{j=1}^{i}gcd(i,j)-\sum_{i=1}^{n}i\\ =\sum_{i=1}^{n}\sum_{j=1}^{i}gcd(i,j)-\frac{n(n+1)}{2} i=1nj=i+1ngcd(i,j)=i=1nj=1igcd(i,j)i=1ni=i=1nj=1igcd(i,j)2n(n+1)

到这一步我们开始推导前半个式子:
∑ i = 1 n ∑ j = 1 i g c d ( i , j ) = ∑ i = 1 n ∑ k = 1 i k ∗ ∑ j = 1 i [ g c d ( i , j ) = k ] \sum_{i=1}^{n}\sum_{j=1}^{i}gcd(i,j)\\ =\sum_{i=1}^{n}\sum_{k=1}^{i}k*\sum_{j=1}^{i}[gcd(i,j)=k] i=1nj=1igcd(i,j)=i=1nk=1ikj=1i[gcd(i,j)=k]

m = i k m=\frac{i}{k} m=ki,那么我们就可以把式子变为:
∑ i = 1 n ∑ j = 1 i g c d ( i , j ) = ∑ i = 1 n ∑ k ∣ i k ∗ ∑ j = 1 m [ g c d ( j , m ) = 1 ] = ∑ i = 1 n ∑ k ∣ i k ϕ ( m ) \sum_{i=1}^{n}\sum_{j=1}^{i}gcd(i,j)\\ =\sum_{i=1}^{n}\sum_{k|i}k*\sum_{j=1}^{m}[gcd(j,m)=1]\\ =\sum_{i=1}^{n}\sum_{k|i}k\phi(m) i=1nj=1igcd(i,j)=i=1nkikj=1m[gcd(j,m)=1]=i=1nkikϕ(m)

m m m代回式子中,即可得到:
∑ i = 1 n ∑ j = 1 i g c d ( i , j ) = ∑ i = 1 n ∑ k ∣ i k ϕ ( i k ) \sum_{i=1}^{n}\sum_{j=1}^{i}gcd(i,j)=\sum_{i=1}^{n}\sum_{k|i}k\phi( \frac{i}{k}) i=1nj=1igcd(i,j)=i=1nkikϕ(ki)

也就是说:
∑ i = 1 n ∑ j = i + 1 n g c d ( i , j ) = ∑ i = 1 n ∑ k ∣ i k ϕ ( i k ) − n ( n + 1 ) 2 \sum_{i=1}^{n}\sum_{j=i+1}^{n}gcd(i,j)= \sum_{i=1}^{n}\sum_{k|i}k\phi(\frac{i}{k})-\frac{n(n+1)}{2} i=1nj=i+1ngcd(i,j)=i=1nkikϕ(ki)2n(n+1)

仔细一思考,发现我们得到的式子大概是这样的:
∑ i = 1 n ( ε × ϕ ) ( i ) \sum_{i=1}^{n}(\varepsilon \times \phi)(i) i=1n(ε×ϕ)(i)

这不就是两个积性函数的dirichlet卷积嘛,直接用dirichlet卷积预处理,然后前缀和一下就可以做到 O ( n log ⁡ n + T ) O(n\log n+T) O(nlogn+T)解决这个问题.

但是我们知道两个积性函数的dirichlet卷积也是一个积性函数,而一般积性函数是可以用线性筛筛的,如果用线性筛预处理的话这道题就可以做到 O ( n + T ) O(n+T) O(n+T)解决了.

那么怎么线性筛呢?我们可以构造一个函数 f f f
f ( i ) = ∑ k ∣ i i k ϕ ( k ) f(i)=\sum_{k|i}\frac{i}{k}\phi(k) f(i)=kikiϕ(k)

考虑使用线性筛筛这个函数 f f f了:
1.当 i i i为素数时, f ( i ) = 2 i − 1 f(i)=2i-1 f(i)=2i1.
2.当 g c d ( i , p r [ j ] ) = 1 gcd(i,pr[j])=1 gcd(i,pr[j])=1时,由于这个函数是积性函数,所以 f ( i ∗ p r [ j ] ) = f ( i ) f ( p r [ j ] ) f(i*pr[j])=f(i)f(pr[j]) f(ipr[j])=f(i)f(pr[j]).
3.当 p r [ j ] ∣ i pr[j]|i pr[j]i时,那么:
f ( i ∗ p r [ j ] ) = ∑ k ∣ i ∗ p r [ j ] i ∗ p r [ j ] k ϕ ( k ) f(i*pr[j])=\sum_{k|i*pr[j]}\frac{i*pr[j]}{k}\phi(k) f(ipr[j])=kipr[j]kipr[j]ϕ(k)

我们设 m u l [ i ] mul[i] mul[i]表示 i i i的所有最小素因子之积,那么:
f ( i ∗ p r [ j ] ) = ∑ k ∣ i i ∗ p r [ j ] k ϕ ( k ) + ∑ k ∣ i m u l [ i ] i ∗ p r [ j ] k ∗ m u l [ i ] ϕ ( k ∗ m u l [ i ] ) = p r [ j ] ∗ f ( i ) + ∑ k ∣ i m u l [ i ] i ∗ p r [ j ] k ∗ m u l [ i ] ϕ ( k ) ∗ ϕ ( m u l [ i ] ) = p r [ j ] ∗ f ( i ) + ∑ k ∣ i m u l [ i ] i ∗ p r [ j ] k ∗ m u l [ i ] ϕ ( k ) ∗ m u l [ i ] ∗ p r [ j ] − 1 p r [ j ] = p r [ j ] ∗ f ( i ) + ( p r [ j ] − 1 ) ∑ k ∣ i m u l [ i ] i k ϕ ( k ) = p r [ j ] ∗ f ( i ) + m u l [ i ] ( p r [ j ] − 1 ) ∑ k ∣ i m u l [ i ] i m u l [ i ] ∗ k ϕ ( k ) = p r [ j ] ∗ f ( i ) + m u l [ i ] ( p r [ j ] − 1 ) f ( i m u l [ i ] ) f(i*pr[j])=\sum_{k|i}\frac{i*pr[j]}{k}\phi(k)+\sum_{k|\frac{i}{mul[i]}}\frac{i*pr[j]}{k*mul[i]}\phi(k*mul[i])\\ =pr[j]*f(i)+\sum_{k|\frac{i}{mul[i]}}\frac{i*pr[j]}{k*mul[i]}\phi(k)*\phi(mul[i])\\ =pr[j]*f(i)+\sum_{k|\frac{i}{mul[i]}}\frac{i*pr[j]}{k*mul[i]}\phi(k)*mul[i]*\frac{pr[j]-1}{pr[j]}\\ =pr[j]*f(i)+(pr[j]-1)\sum_{k|\frac{i}{mul[i]}}\frac{i}{k}\phi(k)\\ =pr[j]*f(i)+mul[i](pr[j]-1)\sum_{k|\frac{i}{mul[i]}}\frac{i}{mul[i]*k}\phi(k)\\ =pr[j]*f(i)+mul[i](pr[j]-1)f(\frac{i}{mul[i]}) f(ipr[j])=kikipr[j]ϕ(k)+kmul[i]ikmul[i]ipr[j]ϕ(kmul[i])=pr[j]f(i)+kmul[i]ikmul[i]ipr[j]ϕ(k)ϕ(mul[i])=pr[j]f(i)+kmul[i]ikmul[i]ipr[j]ϕ(k)mul[i]pr[j]pr[j]1=pr[j]f(i)+(pr[j]1)kmul[i]ikiϕ(k)=pr[j]f(i)+mul[i](pr[j]1)kmul[i]imul[i]kiϕ(k)=pr[j]f(i)+mul[i](pr[j]1)f(mul[i]i)

很明显 m u l [ i ] mul[i] mul[i]是可以在线性筛的时候顺便筛出来的,所以我们就可以愉快的 O ( n + T ) O(n+T) O(n+T)AC这道题啦.

线性筛代码如下:

#include<bits/stdc++.h>
  using namespace std;
 
#define Abigail inline void
typedef long long LL;
 
const int N=5000000;
 
int pr[N+9],b[N+9],tp;
LL mul[N+9],f[N+9],phi[N+9],F[N+9];
 
void sieve(int n){
  for (int i=2;i<=n;++i) b[i]=1;
  mul[1]=1;f[1]=1;phi[1]=1;
  int v;
  for (int i=2;i<=n;++i){
    if (b[i]){
      pr[++tp]=i;
      phi[i]=LL(i-1);
      mul[i]=LL(i);
      f[i]=LL(2*i-1);
    }
    for (int j=1;j<=tp&&i*pr[j]<=n;++j){
      b[v=i*pr[j]]=0;
      if (i%pr[j]==0){
        mul[v]=mul[i]*pr[j];
        phi[v]=phi[i]*pr[j];
        f[v]=f[i]*pr[j]+mul[i]*LL(pr[j]-1)*f[LL(i)/mul[i]];
        break;
      }
      mul[v]=LL(pr[j]);
      phi[v]=phi[i]*phi[pr[j]];
      f[v]=f[i]*f[pr[j]];
    }
  }
  for (int i=1;i<=n;++i)
    F[i]=f[i]+F[i-1];
}
 
Abigail work(){
  sieve(N);
}
 
Abigail getans(){
  int T,n;
  scanf("%d",&T);
  while (T--){
    scanf("%d",&n);
    printf("%lld\n",F[n]-LL(n)*LL(n+1)/2LL);
  }
}
 
int main(){
  work();
  getans();
  return 0;
} 

emmm…顺便也写了一个dirichlet卷积的代码,如果实在看不懂线性筛做法的就参考dirichlet卷积的代码吧:

#include<bits/stdc++.h>
  using namespace std;
 
#define Abigail inline void
typedef long long LL;
 
const int N=5000000;
 
int pr[N+9],b[N+9],tp;
LL phi[N+9],F[N+9];
 
void sieve(int n){
  for (int i=2;i<=n;++i) b[i]=1;
  phi[1]=1;
  for (int i=2;i<=n;++i){
    if (b[i]) pr[++tp]=i,phi[i]=LL(i-1);
    for (int j=1;j<=tp&&pr[j]*i<=n;++j){
      b[i*pr[j]]=0;
      if (i%pr[j]) phi[i*pr[j]]=phi[i]*phi[pr[j]];
      else {phi[i*pr[j]]=phi[i]*pr[j];break;}
    }
  }
}
 
void dirichlet(int n){
  for (int i=1;i<=n;++i)
    for (int j=1;i*j<=n;++j)
      F[i*j]+=phi[i]*j;
  for (int i=1;i<=n;++i)
    F[i]+=F[i-1];
}
 
Abigail work(){
  sieve(N);
  dirichlet(N);
}
 
Abigail getans(){
  int T,n;
  scanf("%d",&T);
  while (T--){
    scanf("%d",&n);
    printf("%lld\n",F[n]-LL(n)*LL(n+1)/2LL);
  }
}
 
int main(){
  work();
  getans();
  return 0;
}

貌似也有一个除法分块的做法可以做到 O ( n + T n ) O(n+T\sqrt{n}) O(n+Tn ),比较慢但是好推一些,原理与上面的式子其实也差不多,这里就不写了.

内容概要:本文提出了一种基于非合作博弈理论的居民负荷分层调度模型,并结合双层鲸鱼优化算法(Two-level Whale Optimization Algorithm)进行高效求解,模型与算法均通过Matlab代码实现。研究针对电力系统中居民侧用电负荷的复杂调度问题,引入非合作博弈机制刻画各用户之间的利益竞争关系,实现负荷的分层优化分配;同时设计双层优化架构,上层优化资源配置,下层模拟用户自主决策行为,提升了模型的实用性与合理性。通过智能优化算法求解多层级、非凸非线性的博弈模型,有效提高了调度方案的收敛性与全局寻优能力,适用于现代智能电网中的需求侧管理与能源优化场景。; 适合人群:具备电力系统基础理论知识Matlab编程能力,从事智能电网、能源优化调度、需求侧管理、博弈论应用等方向的科研人员、高校研究生及工程技术人员。; 使用场景及目标:①应用于居民区电力负荷的分层优化调度系统设计与仿真分析;②为非合作博弈在多主体能源系统建模中的应用提供方法论支持;③利用双层鲸鱼算法解决具有嵌套结构的复杂双层优化问题,提升求解效率与调度方案的可行性。; 阅读建议:建议读者结合提供的Matlab代码深入理解模型构建逻辑与算法实现流程,重点关注博弈模型的效用函数设计、纳什均衡求解思路以及双层优化结构的迭代机制,宜配合实际用电数据开展复现实验以验证模型有效性与鲁棒性。
内容概要:本文围绕基于自适应神经模糊推理系统(ANFIS)智能控制器的可再生能源微电网功率管理系统展开研究,结合Simulink仿真实现,深入探讨了微电网中功率的智能调控与经济机组组合调度问题。通过引入ANFIS控制器,有效应对风能、光伏等可再生能源出力的波动性与不确定性,提升系统运行的稳定性与电能质量。研究内容涵盖微电网多源协调控制策略、功率平衡管理、优化调度模型构建及仿真验证,实现了对分布式电源、储能系统负荷的协同优化,兼顾经济性与可靠性目标,并通过仿真平台验证了所提方法的有效性与优越性。; 适合人群:具备电力系统、自动化或新能源相关专业背景,熟悉Matlab/Simulink仿真环境,从事微电网能量管理、智能控制、能源优化等领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①用于高比例可再生能源接入场景下的微电网能量管理系统研发与教学实践;②为实现微电网功率稳定控制与经济高效运行提供先进的智能控制解决方案;③支撑高水平学术论文复现、科研课题攻关及实际工程项目的仿真验证与方案优化。; 阅读建议:建议结合提供的Simulink模型与相关代码进行动手实践,重点关注ANFIS控制器的设计流程、规则库构建与参数调优方法,并通过与传统PID或MPC控制策略的对比实验,深入理解其在动态响应与鲁棒性方面的优势。同时可进一步拓展文中提出的优化调度逻辑,应用于多目标、多约束的复杂实际应用场景中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值