博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CF871D Paths
阅读量:7122 次
发布时间:2019-06-28

本文共 2511 字,大约阅读时间需要 8 分钟。

 

题意:

n个点的无向图,若$\gcd(x,y) \neq1​$则$(x,y)​$有边,统计$1\sim n​$构成的无向图两两点对最短路是之和是多少(两点不连通最短路记为0)?$n\leq 10^7​$。

 

题解:

先分类讨论一下:

  1. 1和$>\frac n2​$的素数是孤立点,排除掉,其余是一个联通块。
  2. $\gcd(x,y)\neq1\longrightarrow dis(x,y)=1​$
  3. 记$mi[x]$为x的最小素因子,$mi[x]\times mi[y]\leq n\longrightarrow dis(x,y)=2$
  4. 其余均可通过$x \longrightarrow 2\times mi[x] \longrightarrow 2\times mi[y] \longrightarrow y$实现$dis(x,y)=3$

分别考虑:

  1. 直接排除即可
  2. 方案数$=\sum_x x-1-\varphi(x)$
  3. 方案数$=\sum_{x,y}[\gcd(x,y)=1][mi[x]\times mi[y] \leq n]$
  4. 剩余点对

考虑第3种情况怎么求:

“看到$\gcd​$想反演”:

$$
\begin{aligned}
ans&=\sum_{d=1}^n\mu(d)\sum_{d|x}\sum_{d|y}[mi[x]\times mi[y]\leq n]\\
&=\sum_{x=1}^n\sum_{y=1}^n[mi[x]\times mi[y]\leq n]+\sum_{d=2}^n\mu(d)\sum_{d|x}\sum_{d|y}[mi[x]\times mi[y]\leq n]
\end{aligned}
$$
前一部分比较容易求解,直接开桶维护前缀和即可;

后一部分再分类讨论:

1. $d\leq \sqrt{n}​$:由于$d|x​$,所以必定有$mi[x]\leq mi[d]​$,所以对于任意$d|x,d|y​$都有$mi[x]\times mi[y]\leq n​$,所以可行方案数为$(\frac n2)^2​$。

2. $d>\sqrt{n}$:由于$d|x,d|y$,若设$x=k_1d,y=k_2d$,那么有$k_1,k_2\leq \sqrt{n}$,故只有当$k_1=k_2=1$且d为质数时$mi[x]\times mi[y]>n$,可行方案数为$(\frac n2)^2-1$。

那么就只要枚举d就可以$\mathcal{O}(1)$算答案了。

使用线性筛求积性函数$\varphi(i)$和$\mu(i)​$。至此本题解决。

复杂度$\mathcal{O}(n)$。

 

code:

1 #include
2 #define rep(i,x,y) for (int i=(x);i<=(y);i++) 3 #define ll long long 4 5 using namespace std; 6 7 const int N=1e7+10; 8 int n,cnt,phi[N],mu[N],p[N/10],vis[N],T[N],pre[N]; 9 ll sum1,sum2,sum3,ans,all;10 11 void sieve(int n){12 phi[1]=mu[1]=1;13 rep (i,2,n){14 if (!vis[i]) p[++cnt]=vis[i]=i,phi[i]=i-1,mu[i]=-1;15 for (int j=1;j<=cnt&&i*p[j]<=n;j++){16 vis[i*p[j]]=p[j];17 if (i%p[j]==0){phi[i*p[j]]=phi[i]*p[j]; break;}18 phi[i*p[j]]=phi[i]*(p[j]-1);19 mu[i*p[j]]=-mu[i];20 }21 }22 }23 24 int main(){25 scanf("%d",&n); sieve(n);26 rep (i,2,n) if (vis[i]!=i||i<=n/2) all++; all=all*(all-1)/2; //所有非0数对27 rep (i,2,n) sum1+=i-1-phi[i]; ans+=sum1;28 rep (i,2,n) if (vis[i]!=i||i<=n/2) T[vis[i]]++;29 rep (i,2,n) pre[i]=pre[i-1]+T[i];30 rep (i,2,n) if (vis[i]!=i||i<=n/2) sum2+=pre[n/vis[i]]; //不考虑gcd(x,y)=1的条件31 int m=sqrt(n);32 rep (i,2,n){ //减去gcd(x,y)>1的对数:枚举i为>1的gcd33 ll tmp=0;34 tmp+=(ll)(n/i)*(n/i); //vis[ki]<=vis[i]故两个vis[ki]相乘必定<=n35 if (i>m&&vis[i]==i) tmp--; //vis[ki]<=vis[k],而k<=m,故只有当k1=k2=1且i为质数时vis[k1i]*vis[k2i]>n36 sum2+=mu[i]*tmp;37 }38 sum2/=2; ans+=sum2*2;39 ans+=(all-sum1-sum2)*3;40 printf("%lld\n",ans); 41 return 0;42 }
View Code

 

转载于:https://www.cnblogs.com/bestFy/p/10423989.html

你可能感兴趣的文章
Windows Server 2016 配置指南 之 安装 phpMyAdmin
查看>>
分析iOS Crash文件:符号化iOS Crash文件的3种方法
查看>>
[LeetCode]129.Sum Root to Leaf Numbers
查看>>
ganglia mtu metric BUG? on CentOS 6.x x64
查看>>
100的阶层真的算不出来吗?
查看>>
Python-列表和元祖
查看>>
F - Maximum GCD——(UVA 11827)
查看>>
MySQL-Transfer2.3发布
查看>>
BottomNavigationView解决三个限制记录
查看>>
Android拖拽、回弹布局
查看>>
webpack
查看>>
js函数
查看>>
access token
查看>>
爬虫神器pyppeteer,对 js 加密降维打击
查看>>
吃鸡数据不完全分析
查看>>
iOS上下联动框架(Swift)
查看>>
Android RxJava之变换操作符(三)
查看>>
高性能 Web 缓存服务器 nuster 1.7.9.4 发布
查看>>
Java中基本类型占字节数以及Uint32的意思
查看>>
java后台框架 springmvc整合mybatis框架源码 java图片爬虫 bootstrap html5
查看>>