zoukankan      html  css  js  c++  java
  • D. Longest Subsequence

    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,求数组a的最长子序列的最小公倍数不超过m。要求输出其满足要求的任意子序列
     *算法分析:先将小于等于m的数择出来,然后从后向前筛 
    */
    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long int llint;
    const int maxn = 1e6 + 100;
    llint a[maxn], b[maxn];
    
    int main() {
    	memset(a, 0, sizeof(a));
    	memset(b, 0, sizeof(b));
    	llint n, m, flag = 0;
    	scanf("%I64d%I64d",&n, &m);
    	for (llint i = 0; i<n; i++) {
    		scanf("%I64d",&a[i]);
    		if (a[i] <= m) {
    			b[a[i]] ++ ;
    			flag = 1;
    		}
    	}
    	if (!flag)	cout << "1 0" << endl;
    	else {
    		for (llint i = m; i>=1; i--) {
    			for (llint j = 2*i; j<=m; j+=i) {
    				b[j] += b[i];
    			}
    		}
    		llint max = 0, lcm = 0;
    		for (llint i = 1; i<=m; i++) {
    			if (b[i] > max) {
    				max = b[i];
    				lcm = i;
    			}
    		}
    		cout << lcm << " " << max << endl;
    		for (llint i = 0; i<n; i++) {
    			if (lcm%a[i] == 0)	cout << i+1 << " " ;
    		}
    		cout << endl;
    	}
    	return 0;
    }
    
    


  • 相关阅读:
    动态规划专题(二)——树形DP
    动态规划专题(一)——状压DP
    位运算相关(二)——位运算的简单变换操作
    位运算相关(一)——位运算学习笔记
    2018.10.05 TOPOI提高组模拟赛 解题报告
    【BZOJ1088】[SCOI2005] 扫雷Mine(分类讨论)
    【洛谷1273】有线电视网(树上背包)
    【洛谷2264】情书(字符串水题)
    【洛谷4287】[SHOI2011] 双倍回文(Manacher算法经典题)
    【洛谷2051】[AHOI2009] 中国象棋(烦人的动态规划)
  • 原文地址:https://www.cnblogs.com/Tovi/p/6194804.html
Copyright © 2011-2022 走看看