Description

旧试题
skyfall
约数个数和

约数个数和题解

由于这三个题长得比较像就放一起吧
设D(u)D(u)D(u)表示uuu的约数和,那么有如下结论
D(x∗y)=∑u∣x∑v∣y[gcd(u,v)==1]D(x*y)=\sum_{u|x}\sum_{v|y} [gcd(u,v)==1]D(x∗y)=u∣x∑​v∣y∑​[gcd(u,v)==1]
证明如下,设kik_iki​表示质因数pip_ipi​在某个数中的次数
显然约数个数和为Π(ki+1)\Pi(k_i+1)Π(ki​+1)
显然可以知道,x∗yx*yx∗y中的某个kik_iki​一定是在xxx中贡献了uiu_iui​,在yyy中贡献了viv_ivi​并且满足ui+vi=k+iu_i+v_i=k+iui​+vi​=k+i的。那么对于上式,由于gcd(u,v)=1gcd(u,v)=1gcd(u,v)=1,故在x∗yx*yx∗y的某个质因数pip_ipi​中,仅存在三种情况
该质因数被uuu取走,有uiu_iui​种取的次数,该质因数被vvv取走,有viv_ivi​种取的次数,或者两者均不取,有111的次数,则该质因数的合法取法有ui+vi+1=ki+1u_i+v_i+1=k_i+1ui​+vi​+1=ki​+1种,相乘即为约数个数和
拓展到更高维也是一样的
那么式子可以写为
以下均视为n≤mn\leq mn≤m
∑i=1n∑j=1m[gcd(i,j)==1]⌊ni⌋⌊mj⌋\sum_{i=1}^{n}\sum_{j=1}^{m}[gcd(i,j)==1]\lfloor\frac{n}{i}\rfloor\lfloor\frac{m}{j}\rfloori=1∑n​j=1∑m​[gcd(i,j)==1]⌊in​⌋⌊jm​⌋
随意反演一下就可以得到,
∑d=1nμ(d)∗∑i=1⌊nd⌋⌊ni∗d⌋∗∑j=1⌊md⌋⌊mj∗d⌋\sum_{d=1}^{n}\mu(d)*\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\lfloor\frac{n}{i*d}\rfloor*\sum_{j=1}^{\lfloor\frac{m}{d}\rfloor}\lfloor\frac{m}{j*d}\rfloord=1∑n​μ(d)∗i=1∑⌊dn​⌋​⌊i∗dn​⌋∗j=1∑⌊dm​⌋​⌊j∗dm​⌋
注意到有式子⌊ni∗j⌋=⌊⌊ni⌋j⌋\lfloor\frac{n}{i*j}\rfloor=\lfloor\frac{\lfloor\frac{n}{i}\rfloor}{j}\rfloor⌊i∗jn​⌋=⌊j⌊in​⌋​⌋
故上式可写为
∑d=1nμ(d)∗∑i=1⌊nd⌋⌊⌊nd⌋i⌋∗∑j=1⌊md⌋⌊md⌋i⌋\sum_{d=1}^{n}\mu(d)*\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\lfloor\frac{\lfloor\frac{n}{d}\rfloor}{i}\rfloor*\sum_{j=1}^{\lfloor\frac{m}{d}\rfloor}\frac{\lfloor\frac{m}{d}\rfloor}{i}\rfloord=1∑n​μ(d)∗i=1∑⌊dn​⌋​⌊i⌊dn​⌋​⌋∗j=1∑⌊dm​⌋​i⌊dm​⌋​⌋
我写这个的时候没有及时意识到把ddd提上去然后自闭了一会…
nnn\sqrt nnn​预处理一个f(i)=∑j=1i⌊ij⌋f(i)=\sum_{j=1}^{i} \lfloor\frac{i}{j}\rfloorf(i)=∑j=1i​⌊ji​⌋
剩下就可以T∗(n+m)T*(\sqrt n+\sqrt m)T∗(n​+m​)了

skyfall题解

与上一个题式子基本是相同的
在开头枚举一下ccc就可以获得一个n2log⁡nn^2\log nn2logn的做法了
式子是
∑k=1c⌊ck⌋∗∑d=1aμ(d)∗∑i=1⌊ad⌋⌊ai∗d⌋∗[gcd(ad,k)==1]∗∑j=1⌊bd⌋⌊bj∗d⌋∗[gcd(bd,k)==1]\sum_{k=1}^{c}\lfloor \frac{c}{k}\rfloor*\sum_{d=1}^{a}\mu(d)*\sum_{i=1}^{\lfloor\frac{a}{d}\rfloor}\lfloor\frac{a}{i*d}\rfloor*[gcd(ad,k)==1]*\sum_{j=1}^{\lfloor\frac{b}{d}\rfloor}\lfloor\frac{b}{j*d}\rfloor*[gcd(bd,k)==1]k=1∑c​⌊kc​⌋∗d=1∑a​μ(d)∗i=1∑⌊da​⌋​⌊i∗da​⌋∗[gcd(ad,k)==1]∗j=1∑⌊db​⌋​⌊j∗db​⌋∗[gcd(bd,k)==1]
可以直接做了
听说需要卡常

旧试题题解

上面都太naive了啊.
这才是最终的哥哥题
同样运用上面的结论,式子化一下就可以得到
∑da=1max(a,b,c)∑db=1max(a,b,c)∑dc=1max(a,b,c)μ(a)μ(b)μ(c)∗∑i∣lcm(da,db)⌊ai⌋∗∑j∣lcm(db,dc)⌊bj⌋∗∑k∣lcm(da,dc)⌊ck⌋\sum_{da=1}^{max(a,b,c)}\sum_{db=1}^{max(a,b,c)}\sum_{dc=1}^{max(a,b,c)}\mu(a)\mu(b)\mu(c)*\sum_{i|lcm(da,db)}\lfloor\frac{a}{i}\rfloor*\sum_{j|lcm(db,dc)}\lfloor\frac{b}{j}\rfloor*\sum_{k|lcm(da,dc)}\lfloor\frac{c}{k}\rfloorda=1∑max(a,b,c)​db=1∑max(a,b,c)​dc=1∑max(a,b,c)​μ(a)μ(b)μ(c)∗i∣lcm(da,db)∑​⌊ia​⌋∗j∣lcm(db,dc)∑​⌊jb​⌋∗k∣lcm(da,dc)∑​⌊kc​⌋
前面是枚举约数的,用原式换过去不难得到
后面显然可以nlognnlognnlogn直接预处理出来
于是我们考虑怎么算前面合法的a,b,ca,b,ca,b,c的贡献
首先,显然合法的a,b,ca,b,ca,b,c需要满足任意两个数之间的lcm≤max⁡(a,b,c)lcm\leq \max(a,b,c)lcm≤max(a,b,c)
下文不妨设n=max(a,b,c)n=max(a,b,c)n=max(a,b,c)
如果我们给两个合法的数对连上无向边,显然能做出贡献的就是图中的三元环
数三元环的数量是可以做到mmm\sqrt mmm​的,其中mmm为边数证明不会
先介绍如何做到mmm\sqrt mmm​
我们将边定向,满足任意一条边都是从度数较小的点出去,进入度数较大的点
接下来枚举所有点计数,我们发现,原图中存在的任意一个三元环(x,y,c)(x,y,c)(x,y,c)。不妨假定in[x]≤in[y]≤in[z]in[x]\leq in[y]\leq in[z]in[x]≤in[y]≤in[z],在新图中一定满足存在x−>y−>zx->y->zx−>y−>z与x−>zx->zx−>z的路径
故直接枚举第一条路径的两个点判断即可
注意这里的三元环是有顺序的,我们需要做到无序,故要将其六种情况全部讨论一遍
再来建图
枚举有边相连的两个点的gcdgcdgcd,剩余要求互质。
求解过程则是简单问题
注意边用vector存,可以大幅优化常数
但是忽略了两种情况,即选了三个同样的点或者两个同样的点
选三个点时可以直接预处理,选两个点时可以在建边的过程做出来
复杂度估计是不存在的?

旧试题&skyfall

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<ctime>
#include<map>
#include<bitset>
#include<set>
#define LL long long
#define mp(x,y) make_pair(x,y)
#define pll pair<long long,long long>
#define pii pair<int,int>
using namespace std;
inline int read()
{int f=1,x=0;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;
}
int stack[20];
inline void write(int x)
{if(x<0){putchar('-');x=-x;}if(!x){putchar('0');return;}int top=0;while(x)stack[++top]=x%10,x/=10;while(top)putchar(stack[top--]+'0');
}
inline void pr1(int x){write(x);putchar(' ');}
inline void pr2(int x){write(x);putchar('\n');}
const int MAXN=100005;
const int mod=1e9+7;
struct edge
{int x,y,c;edge(){}edge(int _x,int _y,int _c){x=_x;y=_y;c=_c;}
};
vector<pii> vec[MAXN];
vector<edge> vec1;
int mu[MAXN],pr[MAXN],plen;
bool is[MAXN];
void getmu(int N)
{mu[1]=1;for(int i=2;i<=N;i++){if(!is[i])mu[i]=-1,pr[++plen]=i;for(int j=1;i*pr[j]<=N&&j<=plen;j++){is[i*pr[j]]=true;if(!(i%pr[j]))mu[i*pr[j]]=0;else mu[i*pr[j]]=-mu[i];}}
}
int A,B,C,n,m;
LL ans;
LL fa[MAXN],fb[MAXN],fc[MAXN];
void getf(LL *y,int len)
{for(int i=1;i<=len;i++)for(int j=1;i*j<=len;j++)y[i]+=len/(i*j);for(int i=1;i<=len;i++)y[i]%=mod;
}
void work1(){for(int i=1;i<=m;i++)ans+=fa[i]*fb[i]*fc[i]*mu[i]*mu[i]*mu[i]%mod;}
int du[MAXN];
int gcd(int a,int b){return a==0?b:gcd(b%a,a);}
void prering()
{vec1.clear();memset(du,0,sizeof(du));for(int GCD=1;GCD<=n;GCD++)for(int u1=1;u1*GCD<=n;u1++)if(mu[u1*GCD])for(int u2=u1+1;1LL*u2*u1*GCD<=n;u2++)if(gcd(u1,u2)==1&&mu[u2*GCD]){int x=u1*GCD,y=u2*GCD,lcm=u1*u2*GCD;
//          if(lcm>n)continue;ans+=mu[x]*mu[x]*mu[y]*(fa[x]*fb[lcm]*fc[lcm]+fa[lcm]*fb[x]*fc[lcm]+fa[lcm]*fb[lcm]*fc[x]);ans+=mu[x]*mu[y]*mu[y]*(fa[y]*fb[lcm]*fc[lcm]+fa[lcm]*fb[y]*fc[lcm]+fa[lcm]*fb[lcm]*fc[y]);vec1.push_back(edge(x,y,lcm));du[x]++;du[y]++;}for(int i=0;i<vec1.size();i++){int x=vec1[i].x,y=vec1[i].y,lcm=vec1[i].c;if(du[x]<du[y])vec[x].push_back(mp(y,lcm));else vec[y].push_back(mp(x,lcm));}
}
int nxt[MAXN],lm[MAXN],tim;
void solve()
{for(int i=1;i<=n;i++)if(mu[i]){tim++;for(int j=0;j<vec[i].size();j++)nxt[vec[i][j].first]=tim,lm[vec[i][j].first]=vec[i][j].second;for(int j=0;j<vec[i].size();j++){int y=vec[i][j].first;for(int k=0;k<vec[y].size();k++){int z=vec[y][k].first;if(nxt[z]!=tim)continue;int x=i;int lm1=vec[i][j].second,lm2=vec[y][k].second,lm3=lm[z],mul=mu[x]*mu[y]*mu[z];ans+=mul*(fa[lm1]*fb[lm2]*fc[lm3]+fa[lm1]*fb[lm3]*fc[lm2]+fa[lm2]*fb[lm1]*fc[lm3]+fa[lm2]*fb[lm3]*fc[lm1]+fa[lm3]*fb[lm1]*fc[lm2]+fa[lm3]*fb[lm2]*fc[lm1]);}}}
}
int main()
{getmu(MAXN-1);int T=read();while(T--){for(int i=1;i<=n;i++)vec[i].clear();A=read();B=read();C=read();ans=0;memset(fa,0,sizeof(fa));memset(fb,0,sizeof(fb));memset(fc,0,sizeof(fc));getf(fa,A);getf(fb,B);getf(fc,C);n=max(A,max(B,C));m=min(A,min(B,C));memset(nxt,0,sizeof(nxt));tim=0;work1();prering();solve();pr2((ans%mod+mod)%mod);}return 0;
}

约数个数和

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<ctime>
#include<map>
#include<bitset>
#include<set>
#define LL long long
#define mp(x,y) make_pair(x,y)
#define pll pair<long long,long long>
#define pii pair<int,int>
using namespace std;
inline int read()
{int f=1,x=0;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;
}
int stack[20];
inline void write(LL x)
{if(x<0){putchar('-');x=-x;}if(!x){putchar('0');return;}int top=0;while(x)stack[++top]=x%10,x/=10;while(top)putchar(stack[top--]+'0');
}
inline void pr1(int x){write(x);putchar(' ');}
inline void pr2(LL x){write(x);putchar('\n');}
const int MAXN=50005;
int mu[MAXN],pr[MAXN],plen;
bool is[MAXN];
void getpr(int N)
{mu[1]=1;for(int i=2;i<=N;i++){if(!is[i])mu[i]=-1,pr[++plen]=i;for(int j=1;i*pr[j]<=N&&j<=plen;j++){is[i*pr[j]]=true;if(!(i%pr[j]))mu[i*pr[j]]=0;else mu[i*pr[j]]=-mu[i];}}for(int i=2;i<=N;i++)mu[i]+=mu[i-1];
}
LL f[MAXN];
int main()
{getpr(MAXN-1);for(int i=1;i<MAXN;i++)for(int j=1,nxt;j<=i;j=nxt+1){nxt=i/(i/j);f[i]+=1LL*(nxt-j+1)*(i/j);}int T=read();while(T--){int n=read(),m=read();if(n>m)swap(n,m);LL ans=0;for(int i=1,nxt;i<=n;i=nxt+1){nxt=min(n/(n/i),m/(m/i));ans+=1LL*(mu[nxt]-mu[i-1])*f[n/i]*f[m/i];}pr2(ans);}return 0;
}

[bzoj5332][bzoj5276][bzoj3994][莫比乌斯反演][三元环计数]旧试题/skyfall/约数个数和相关推荐

  1. P4619 [SDOI2018]旧试题(莫比乌斯反演,建图优化三重枚举,三元环计数,神仙好题,超级清晰易懂)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 P4619 [SDOI2018]旧试题(莫比乌斯反演,三元环计数) Problem 计算: ∑i=1A ...

  2. 牛客挑战赛51 E NIT的gcd(欧拉反演,建图优化,三元环计数)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Problem 给你一个正整数 nnn. 请你输出 ∑i=1n∑j=1n∑k=1ngcd⁡(i,j)g ...

  3. 三元环计数四元环计数

    三元环计数 问题 给出一张n个点m条边的无向图,问图中有多少个三元组{ u , v , w } ,满足图中存在 { (u,v) , (v,w) , (w,u) } 三条边. 求解 Step1 定向 将 ...

  4. 洛谷 - P1989 无向图三元环计数(思维建图)

    题目链接:点击查看 题目大意:给出一个 nnn 个点 mmm 条边组成的无向图,求三元环的个数 题目分析:对于原图建新图,对于原来的每条边来说 如果度数不同,度数小的点指向度数大的点 如果度数相同,编 ...

  5. HDU6184【Counting Stars】(三元环计数)

    题面 传送门 给出一张无向图,求 \(4\) 个点构成两个有公共边的三元环的方案数. 题解 orz余奶奶,orz zzk 首先,如果我们知道经过每条边的三元环个数\(cnt_i\),那么答案就是\(\ ...

  6. P1989 无向图三元环计数 思维 + 建图

    传送门 文章目录 题意: 思路: 题意: 统计无向图中三元环的个数. 思路: 很明显有一种暴力的方法,就是枚举每条边,让后再跑两个点的所有边,可以卡到复杂度O(m2)O(m^2)O(m2). 我们可以 ...

  7. 基站建设(三元环计数+根号分治 / bitset)

    基站建设 problem solution code problem 给定 nnn 个地点,以及每个地点的可靠度 RiR_iRi​. 有 mmm 条光纤架,每一条连接两个不同的地点,且是双向的. 测试 ...

  8. 【HDU - 6184】Counting Stars(三元环计数,二分,优化暴力,O(m*sqrt(m)),图论)

    题干: Little A is an astronomy lover, and he has found that the sky was so beautiful! So he is countin ...

  9. 【Codeforces - 找不到题号】三元环计数(bitset优化,压位)

    题干: 给你一个二维字符矩阵,如果 ( i , j ) 为+ 表明 两点之间有一条有向边,为-表示没有边,那么你要找出所有的三元环的个数.顶点数N<=1500. 解题报告: 考虑最暴力的方法,开 ...

  10. 【数学专题】莫比乌斯反演与积性函数

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的模板整合计划 目录 莫比乌斯反演 AcWing 2702. problem b AcWing 1358. 约数个数和(莫 ...

最新文章

  1. AOP切入点表达式 ——within表达式 、execution()表达式
  2. 假设一个半衰期为0的对象
  3. 全球及中国金属粘合剂行业需求规模及产销前景分析报告2022-2027年
  4. 2021信阳高中高考成绩查询,河南省普通高中综合信息管理系统2021信阳中考成绩查询入口...
  5. 这个女生躲在衣柜等男友回家,结果竟是......
  6. 前端学习(1972)vue之电商管理系统电商系统之弹出修改对话框
  7. PHP本地服务器localhost与数据库MySQL的综合运用
  8. C# 算法之链表、双向链表以及正向反向遍历实现
  9. 实数集r用区间表示为_七大实数理论与互推
  10. Kotlin协程简介(一) Hello,coroutines!
  11. lenovo L480 进入bios_小白福利教程:如何刷显卡BIOS以及强刷显卡BIOS(一)
  12. 蓝桥杯 明码题解 【Java实现】
  13. Arduino_Core_STM32---pinMode()实现分析
  14. 忆我的大学老师----(一)
  15. 设计模式 ---建造者模式
  16. 计算机冗余,惯性导航计算机系统冗余设计
  17. 我如何为我的第一个自由客户构建第一个React Native应用程序
  18. WebRTC音视频采集和播放示例及MediaStream媒体流解析
  19. 阿里云轻量服务器使用一年使用体验(个人心得,仅供参考)
  20. autopoi-web 导入 excel 解决二级表头重复问题(含前端示例)

热门文章

  1. STM32L476入坑-1
  2. git小乌龟的安装和使用教程
  3. noob_CSS:从Noob到Ninja
  4. 提高迅雷下载速度的方法
  5. AABB和OBB包围盒简介
  6. python 爬取学信网登录页面
  7. java整钱兑零美元换算成美分,人民币和美元大写格式在线工具,美元美金数字金额转换大写,外币大写金额...
  8. 小程序增加 文章 / 新闻 / 资讯 / 动态 功能,支持用户投稿
  9. .NET EF(Entity Framework)详解
  10. 校园歌手大赛10分c语言,校园歌手大赛评分细则