Codeforces 871D Paths (欧拉函数 + 结论)

题目链接  Round  #440  Div 1  Problem D

题意   把每个数看成一个点,如果$gcd(x, y) \neq 1$,则在$x$和$y$之间连一条长度为$1$的无向边。

     设$d(u, v)$为$u$到$v$之间的最短路,如果$u$和v不连通那么$d(u, v) = 0$

     现在给定$n$,求所有的满足$1 <= u < v <= n$的$d(u, v)$之和。

首先把$1$和大于$\frac{n}{2}$的质数去掉,这些数和任何数之间的最短距离为$0$。

我们可以得出对于任意$u$, $v$,都有$d(u, v) <= 3$

若$u$和$v$非互素,那么$d(u, v) = 1$;

令$p(x)$为$x$的最小质因子。如果$p(u) \cdot p(v) <= n$,那么$d(u, v) = 2$

路径为$u - p(u) \cdot p(v) - v$

否则一定存在一条长度为3的路径:$u - 2u - 2v - v$

那么只要求出这三种路径的条数就可以了。

对于长度为$1$的路径,利用欧拉函数可以轻松求出。

对于长度为$2$的路径,设$c[x]$为$p[u] = x$的$u$的个数,$s[]$为$c[]$的前缀和。

那么长度为$2$的路径条数为$∑c_{i} * s_{[\frac{n}{i}]}$,注意去掉长度为$1$的情况。

最后长度为$3$的路径条数就是总的合法点对数减去长度为$1$的路径和长度为$2$的路径条数。

时间复杂度$O(nlogn)$

#include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b)	for (int i(a); i <= (b); ++i)
#define dec(i, a, b)	for (int i(a); i >= (b); --i)
#define MP		make_pair
#define fi		first
#define se		second

typedef long long LL;

const int N = 1e7 + 10;

int pri[N], p[N], phi[N], c[N], s[N];
int n, m, tot, now;
LL  s1, s2, s3;

int main(){

	scanf("%d", &n);
	phi[1] = 1;
	rep(i, 2, n){
		if (!p[i]){
			p[i] = pri[++tot] = i;
			phi[i] = i - 1;

		}

		rep(j, 1, tot){
			if (i * pri[j] > n) break;
			p[i * pri[j]] = pri[j];
			if (i % pri[j] == 0){
				phi[i * pri[j]] = phi[i] * pri[j];
				break;
			}
			else phi[i * pri[j]] = phi[i] * (pri[j] - 1);
		}
	}

	rep(i, 2, n) s1 += 0ll + i - 1 - phi[i];
	rep(i, 2, n) ++c[p[i]];
	rep(i, 2, n) s[i] = s[i - 1] + c[i];
	rep(i, 2, n) s2 += 1ll * c[i] * s[n / i];
	rep(i, 2, n) if (1ll * p[i] * p[i] <= n) --s2;

	s2 /= 2;
	s2 -= s1;
	m  = n - 1;
	dec(i, tot, 1){
		if (pri[i] * 2 > n) --m;
		else break;
	}

	s3 = 1ll * m * (m - 1) / 2 - s1 - s2;
	printf("%lld\n", s1 + 2 * s2 + 3 * s3);
	return 0;
}

  

原文地址:https://www.cnblogs.com/cxhscst2/p/8620758.html

时间: 2024-08-30 08:04:50

Codeforces 871D Paths (欧拉函数 + 结论)的相关文章

Codeforces 906D Power Tower(欧拉函数 + 欧拉公式)

题目链接  Power Tower 题意  给定一个序列,每次给定$l, r$ 求$w_{l}^{w_{l+1}^{w_{l+2}^{...^{w_{r}}}}}$  对m取模的值 根据这个公式 每次递归计算. 因为欧拉函数不断迭代,下降到$1$的级别大概是$log(m)$的,那么对于每一次询问最多需要递归$log(m)$次 注意每次求解欧拉函数的时候要用map存下来,方便以后查询 #include <bits/stdc++.h> using namespace std; #define re

欧拉函数小结

欧拉函数: φ(n)表示1~n中和n互素的数目 要处理出欧拉函数.先证明φ(p)=p-1.(p为素数) 根据互素的概念.两个数的公约数只有1,那么这两个数互素.再根据素数的定义.公约数除了本身以外只有1的数为素数.所以得证φ(p) = p-1. 再证明欧拉函数为不完全积性函数. φ(m1*m2) = φ(m1)*φ(m2) 其中 m1和m2互素.即gcd(m1,m2)=1. 证明过程在我另外一篇博文中.我觉得那种证明比较好.当然还有别的比较好的证明方法. http://www.cnblogs.c

数论 - 欧拉函数模板题 --- poj 2407 : Relatives

Relatives Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11372   Accepted: 5544 Description Given n, a positive integer, how many positive integers less than n are relatively prime to n? Two integers a and b are relatively prime if ther

[ACM] POJ 2154 Color (Polya计数优化,欧拉函数)

Color Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7630   Accepted: 2507 Description Beads of N colors are connected together into a circular necklace of N beads (N<=1000000000). Your job is to calculate how many different kinds of th

POJ2480 Longge&#39;s problem 欧拉函数的应用 &amp;&amp; 积性函数

题意很简单,求sum(gcd(i,n))   1<=i<=n; 这题看到后第一反应并没有里用积性函数的性质,不过也可以做,欣慰的是我反应还是比较快的 设f(n)=gcd(1,n)+gcd(2,n)+....+gcd(n-1,n) + gcd(n,n), 用g(n,i)表示满足 gcd(x,n)=i的 x的个数 (x小于n),则 f(n)=sum{i*g(n,i)}; 同时又利用 扩展欧几里德的性质  gcd(x,n)=i  的充要条件是 gcd(x/i,n/i)==1,所以 满足 x/i的解有

【欧拉函数】欧拉函数前缀和

转自http://www.cnblogs.com/chanme/p/4457200.html H.   Game Alice likes to play games. One day she meets such a game. There are N * N switches arranged in an N * N array. Pressing a switch would change its state, from off to onor from on to off. In addi

【poj2478-Farey Sequence】递推求欧拉函数-欧拉函数的几个性质和推论

http://poj.org/problem?id=2478 题意:给定一个数x,求<=x的数的欧拉函数值的和.(x<=10^6) 题解:数据范围比较大,像poj1248一样的做法是不可行的了. 首先我们要了解欧拉函数的几个性质和推论:(今天跟好基友Konjak魔芋讨论了好久..) 推论(一): phi(p^k)=(p-1)*p^(k-1) 证明: 令n=p^k,小于等于n的正整数数中,所有p的倍数共有p^k /p = p^(k-1)个. 1~n出去p的倍数,所以phi(n)= n -  p^

费马小定理,欧拉函数

在证明这些定理之前先证明一个有意思的定理. 对于0 mod m,n mod m , 2n mod m, 3n mod m, 4n mod m... (m-1)n mod m 对应解集序列 一定有 m/d份 0 d 2d 3d..m-d. (不一定按照顺序) 这样的解. 其中d = gcd(n,m) 具体点:n=8,m=12.  d = gcd(n,m)=4 对于 0 mod 12,8 mod 12,16 mod 12,24 mod 12,32 mod 12,40 mod 12...88 mod

UVa 11426 (欧拉函数 GCD之和) GCD - Extreme (II)

题意: 求sum{gcd(i, j) | 1 ≤ i < j ≤ n} 分析: 有这样一个很有用的结论:gcd(x, n) = i的充要条件是gcd(x/i, n/i) = 1,因此满足条件的x有phi(n/i)个,其中Phi为欧拉函数. 所以枚举i和i的倍数n,累加i * phi(n/i)即可. 1 #include <cstdio> 2 typedef long long LL; 3 4 const int maxn = 4000000; 5 6 int phi[maxn + 10]