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; }