CF 632 D 技巧题

唉,这两天电脑坏了,一直没做题,感觉心有点慌慌的。

今天接着开始做CF了,感觉这道题很好,又掌握了很多知识。

http://codeforces.com/contest/632/problem/D


D. Longest Subsequence
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

You are given array a with n elements and the number m. Consider some subsequence of a and the value of least common multiple (LCM) of its elements. Denote LCM as l. Find any longest subsequence of a with the value l ≤ m.

A subsequence of a is an array we can get by erasing some elements of a. It is allowed to erase zero or all elements.

The LCM of an empty array equals 1.

Input

The first line contains two integers n and m (1 ≤ n, m ≤ 106) — the size of the array a and the parameter from the problem statement.

The second line contains n integers ai (1 ≤ ai ≤ 109) — the elements of a.

Output

In the first line print two integers l and kmax (1 ≤ l ≤ m, 0 ≤ kmax ≤ n) — the value of LCM and the number of elements in optimal subsequence.

In the second line print kmax integers — the positions of the elements from the optimal subsequence in the ascending order.

Note that you can find and print any subsequence with the maximum length.

Examples
input
7 8
6 2 9 2 7 2 3
output
6 5
1 2 4 6 7
input
6 4
2 2 2 3 3 3
output
2 3
1 2 3




题目大意:给n个数字的数组a,然后其中lcm最大是m,求最长公子序列,使该公共子序列的lcm小于等于m。输出len,公共子序列的lcm和下标


思路:因为是lcm,所以构成该lcm的子序列的数组元素都一定能被lcm整除。然后只要每次都枚举一下cnt就可以统计出len的最长的长度了(这里枚举的是i的倍数,而不是m^2,不然会TLE的)。然后还有一个注意点,因为数组元素最大是10^9,而m只有10^6,所以,大于m的都不要放进来就可以了。


#include<cstdio> #include<algorithm> #include<cstring> using namespace std; typedef pair<int int=""> P; typedef long long ll; const ll maxn = 1000000 + 10; const ll inf = 0x3f3f3f3f; ll n, m; ll a[maxn]; ll cnt[maxn]; ll len[maxn]; void solve(){ for (int i = 1; i <= m; i++){ for (int j = i; j <= m; j += i){ len[j] += cnt[i]; } } ll maxlcm = 1, maxlen = 0; for (int i = 1; i <= m; i++){ if (len[i] > maxlen){ maxlcm = i; maxlen = len[i]; } } printf("%I64d %I64d\n", maxlcm, maxlen); if (maxlen == 0) return ; int flag = 0; for (int i = 1; i <= n; i++){ if (maxlcm % a[i] == 0) {printf("%d", i); flag = 1;} if (flag == 1){ printf("%c", i == n ? '\n' : ' '); flag = 0; } } } int main(){ while (scanf("%I64d%I64d", &n, &m) == 2){ for (int i = 1; i <= maxn; i++){ cnt[i] = 0; len[i] = 0; a[i] = 0; } for (int i = 1; i <= n; i++){ scanf("%I64d", &a[i]); if(a[i] <= m) cnt[a[i]]++; } solve(); } return 0; } </int></cstring></algorithm></cstdio>

你可能感兴趣的:(CF 632 D 技巧题)