第九届ECNU Coder K.计软联谊

题目链接:http://acm.ecnu.edu.cn/contest/16/problem/K/

题目:

K. 计软联谊

Time limit per test: 7.0 seconds

Time limit all tests: 7.0 seconds

Memory limit: 512 megabytes

Accept / Submit: 19 / 398

在计算机和软件专业的联谊会上,计算机和软件的同学相间着排成一列。现在要计算相邻两个同学的友谊度。

友谊度 friend(a,b) 是这么计算的:令 ab 两个整数分别是两个同学的属性,两个同学的友谊度取决于 a,b 第 k 大的公约数。如果不存在,就说明这两个同学之间完全没有友谊,友谊度为 1

Input

第一行是数据组数 T (1T60)

对于每组数据:
第一行:首先是学生的数量 n (1n105),约定的常数 k (1k106)
第二行:n 个整数,依次表示这些学生的属性值:m1,m2,,mn (1mi106)

Output

对于每组数据输出一行,以 Case x: 开头(x 表示数据编号,从 1 开始),后面是 n1 个整数,分别是 friend(m1,m2),friend(m2,m3),,friend(mn1,mn),整数和整数之间用空格隔开。

Examples

input
2
3 1
4 6 12
6 2
13 12 12 24 36 30
output
Case 1: 2 6
Case 2: -1 6 6 6 3

Note

请注意输入输出上的优化!

题解:

  就每两个数gcd,求出最大公约数。然后求第k大的公约数。

  一开始理解错,以为第2大的公约数是最大公约数除以2,第3大则是除以4。dalao说是错的。

  第k大的公约数是最大公约数的约数(不一定是除以2,可以除以3什么的)。

  就先用筛法将1~1e6的每个数的约数筛出来。

  

1 void init() {
2     for(int i = 1;i<=L;i++){
3         for(int j = i;j<=L;j+=i){
4             P[j].push_back(i);
5         }
6     }
7 }
筛法

  详细代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <cmath>
 6 #include <string>
 7 #include <vector>
 8 #include <map>
 9 #include <set>
10 #include <stack>
11 #include <queue>
12 #include <sstream>
13 #include <algorithm>
14 using namespace std;
15 #define pb push_back
16 #define mp make_pair
17 #define ms(a, b)  memset((a), (b), sizeof(a))
18 #define eps 0.0000001
19 typedef long long LL;
20 typedef unsigned long long ULL;
21 const int inf = 0x3f3f3f3f;
22 const LL INF = 0x7fffffff;
23 const int maxn = 1e5+10;
24 const int L = 1e6;
25 const int mod = 1e9+7;
26 int m[maxn];
27 vector <int > P[L+1];
28 int kase = 1;
29 void init() {
30     for(int i = 1;i<=L;i++){
31         for(int j = i;j<=L;j+=i){
32             P[j].push_back(i);
33         }
34     }
35 }
36 int gcd(int a, int b){
37     return b==0?a:gcd(b, a%b);
38 }
39 void solve() {
40     int n, k;
41     scanf("%d%d", &n, &k);
42     for(int i = 1;i<=n;i++)
43         scanf("%d", &m[i]);
44     printf("Case %d:", kase++);
45     for(int i = 1;i<n;i++){
46         int x = gcd(m[i], m[i+1]);
47         int len = P[x].size();
48         if(len-k>=0){
49             printf(" %d", P[x][len-k]);
50         }
51         else
52             printf(" -1");
53     }
54     printf("
");
55 }
56 int main() {
57 #ifdef LOCAL
58     freopen("input.txt", "r", stdin);
59 //      freopen("output.txt", "w", stdout);
60 #endif // LOCAL
61     init();
62     int T;
63     scanf("%d", &T);
64     while(T--){
65         solve();
66     }
67     return 0;
68 }
View Code

你努力的时候,比你厉害的人也在努力。

原文地址:https://www.cnblogs.com/denghaiquan/p/6885480.html