codeforces 1009D Relatively Prime Graph【欧拉函数】

题目:戳这里

题意:要求构成有n个点,m条边的无向图,满足每条边上的两点互质。

解题思路:

显然1~n这n个点能构成边的条数,就是2~n欧拉函数之和(x的欧拉函数值代表小于x且与x互质的数的个数。

因此m>n-1 && m <= sum成立则可以构成无向图。

接着求出1e5以内的欧拉函数,求和可以发现前1000项的欧拉值就已经远远大于1e5。

所以m条边直接两层循环暴力即可。

附本人代码:

 1 #include <bits/stdc++.h>
 2 typedef long long ll;
 3 const int maxn = 1e5+10;
 4 const ll inf = 1e18;
 5 const ll mod = 1e9+7;
 6 using namespace std;
 7 ll cnt[maxn];
 8 ll euler[maxn];
 9 void geteuler() {
10     memset(euler, 0, sizeof(euler));
11     euler[1] = 1;
12     for(ll i = 2; i < maxn; ++i) {
13         if(!euler[i]) {
14             for(ll j = i; j < maxn; j+=i) {
15                 if(!euler[j]) euler[j] = j;
16                 euler[j] = euler[j]/i * (i - 1ll);
17             }
18         }
19     }
20 }
21 ll gcd(ll a, ll b) {return b?gcd(b,a%b):a;}
22 int main(){
23     ll n, m;
24     ll sum = 0;
25     scanf("%lld %lld", &n, &m);
26     geteuler();
27     for(ll i = 2; i <= n; ++i) {
28         sum += euler[i];
29     }
30 
31   //  printf("%lld\n", sum);
32     if(sum < m || m < n - 1) {
33         puts("Impossible");
34         return 0;
35     }
36     puts("Possible");
37     for(ll i = 1; i <= n; ++i) {
38         for(ll j = i + 1; j <= n; ++j) {
39             if(gcd(i,j)==1) {
40                 printf("%lld %lld\n", i, j);
41                 --m;
42                 if(!m) return 0;
43             }
44         }
45     }
46     return 0;
47 }
View Code

 

posted @ 2018-11-19 14:00  euzmin  阅读(192)  评论(0编辑  收藏  举报