D. Longest Subsequence

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

找出一个最长的序列,使其最小公倍数小于等于m,输出最小公倍数和序列的长度,在下一行输出每个数字的位置

做法:因为m大小只有1e6,可以暴力找所有小于m的数,看他的序列是不是最长,前面处理的时候,把每个数字的个数算出来,如何从1到m,把他的倍数都加上他自己的个数,这处理完,每一个数组中的数字,对应的就是以他为倍数的个数了,如何暴力找就可以了

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<map>
#include<vector>
#include<queue>
#include<stack>
#define sf scanf
#define scf(x) scanf("%d",&x)
#define scff(x,y) scanf("%d%d",&x,&y)
#define scfff(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define vi vector<int>
#define mp make_pair
#define pf printf
#define prf(x) printf("%d\n",x)
#define mm(x,b) memset((x),(b),sizeof(x))
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=a;i>=n;i--)
typedef long long ll;
using namespace std;
const ll mod=1e9+7;
const double eps=1e-6;
const double pi=acos(-1.0);
const int inf=0x7fffffff;
const int N=1e6+7;
int a[N];
int sum[N];
int lcm(int x,int y)
{
    return x*y/(__gcd(x,y));
 } 
map<int,int> v;
int main()
{
    int n,m;scff(n,m);
    rep(i,0,n)
    {
        scf(a[i]);
        if(a[i]<=m)
        {
            v[a[i]]++;
        }
    }
    mm(sum,0);
    rep(i,1,m+1)
    {
        if(v[i])
        for(int j=i;j<=m;j+=i)
        {
            sum[j]+=v[i];
        }
    }
    int maxn=0,maxk=1;
    rep(i,1,m+1)
    {
        if(sum[i]>maxn)
        maxk=i;
        maxn=max(maxn,sum[i]);
    }
    cout<<maxk<<" "<<maxn<<endl;
    int node=0;
    rep(i,0,n)
    {
        if(maxk%a[i]==0)
        {
            if(node==0)
            pf("%d",i+1),node++;
            else
            pf(" %d",i+1);
        }
    }
    return 0;
}

转载于:https://www.cnblogs.com/wzl19981116/p/10833598.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值