http://codeforces.com/contest/632/problem/D
给n个数,给m
求出一个子串,其LCM<=m,求出最长的子串并输出
n,m<=1e6
想到直接枚举m
对每个m,看其因子个数即可,至于因子个数的话,m最大1e6,可以打一个表
即对a[i],把其所有小于m的倍数都计数加1,后来发现如果a[i]全是小的,铁TLE。
于是可以预先统计a[i]的个数,那么对每个数,只需要跑一遍
最极端数据是 1 2 3 4.....1e6
计算过这样要刚好跑 1e7次,可行
打完表,直接从1到m遍历,找到因子个数最多的那个,记录,输出
忘记特判 k=0的情况。。被cha了。。
<pre name="code" class="cpp">#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;
const double pi=acos(-1.0);
double eps=0.000001;
int min(int a,int b)
{
return a<b?a:b;
}
int mp[1000000+50];
int tm[1000000+50];
int vis[1000000+50];
int main()
{
int i;
int n,m;
cin>>n>>m;
for (i=1;i<=n;i++)
{
scanf("%d",&tm[i]);
if (tm[i]<=m)
vis[tm[i]]++;
}
for (i=1;i<=m;i++)
{
int p=i;
while(p<=m)
{
mp[p]+=vis[i];
p+=i;
}
}
int maxx=0;
int who=-1;
for (i=1;i<=m;i++)
{
if (mp[i]>maxx)
{
maxx=mp[i];
who=i;
}
}
if (who==-1)
{
printf("1 0\n");
return 0;
}
printf("%d %d\n",who,maxx);
int line=0;
for (i=1;i<=n;i++)
{
if (who%tm[i]==0)
{
if (line) printf(" ");
printf("%d",i);
line=1;
}
}
printf("\n");
return 0;
}