zoukankan      html  css  js  c++  java
  • CF632D 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 ≤ 10^6) — the size of the array a and the parameter from the problem statement.

    The second line contains n integers ai (1 ≤ ai ≤ 10^9) — 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
    一句话题意:

    分析:对于一个数k,它的所有约数的lcm肯定不大于k,也就是说对于每一个[1,m]中的数,我们只需要求出它的约数是a中的数的个数就好了,难道又要用筛法或质因数分解吗?其实不必,我们可以想到一个O(nm)的做法:枚举[1,m]中的每一个数,然后看看a中有多少个数整除它,显然T掉,能不能改进一下呢?
    对于枚举的优化,要么是减少枚举层数,要么是减少对答案没有贡献的枚举,我们可以只用枚举整除数i的数,然后看看a中有没有这个数,这个操作可以用一个vis数组,只需要O(1)的时间查询。不过ai <= 10^9,我们似乎开不下这么大的vis数组,观察题目,发现m只有10^6,大于10^6的数我们可以不用考虑.
    其实相对于枚举约数,枚举倍数更容易,我们从一个数扩展,将它的倍数的计数器累加即可,其实两种方法都可以.
    #include <cstdio>
    #include <queue>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <cmath>
    
    using namespace std;
    
    const int maxn = 1000010;
    
    int num[maxn], cnt[maxn],tot,a[maxn],ans,id,vis[maxn];
    int n, m;
    
    int main()
    {
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; i++)
        {
            int t;
            scanf("%d", &t);
            a[i] = t;
            if (t > m)
                continue;
            ++num[t];
        }
        for (int i = 1; i <= n; i++)
        {
            if (!vis[a[i]])
            for (int j = a[i]; j <= m; j += a[i])
                cnt[j] += num[a[i]];
            vis[a[i]] = 1;
        }
        for (int i = 1; i <= m; i++)
            if (cnt[i] > ans)
            {
                ans = cnt[i];
                id = i;
            }
        printf("%d %d
    ", id, ans);
        for (int i = 1; i <= n; i++)
            if (id % a[i] == 0)
                printf("%d ", i);
    
        return 0;
    }

  • 相关阅读:
    防止SQL注入
    Sql Server参数化查询之where in和like实现详解
    NET下载文件报错System.UnauthorizedAccessException的解决方法
    hibernate 中的session和事务(Transaction)
    ASP.net MVC 文件下载的几种方法
    SQLServer中查询表结构(表主键 、列说明、列数据类型、所有表名)的Sql语句
    NHibernate 中删除数据的几种方法
    SQL、LINQ、Lambda 三种用法(转)
    .net MVC 单页面 多个(行)数据修改
    绘制你的第一个图表(jquery-flot-line-chart)
  • 原文地址:https://www.cnblogs.com/zbtrs/p/7391207.html
Copyright © 2011-2022 走看看