cf#ecr9-D - Longest Subsequence

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

 

你可能感兴趣的:(cf#ecr9-D - Longest Subsequence)