P2926 [USACO08DEC]Patting Heads S

原题链接
考察:约数
这题很久以前做过一次,但我没写博客,结果再来一次我还是不会(.)
错误思路:
  倍数法求每个a[i]的倍数,基本代码如下:

for(int i=1;i<=n;i++)
{
    scanf("%d",&a[i]);
    for(int j=1;j<=M/a[i];j++)
    sum[j*a[i]]++;
}

  一旦数据出现大量1+1e6或者其他小的数,时间复杂度会退化到O(n、*m)还是十分恐怖
正确思路:
  如果不能倍数法求约数就考虑试除法求约束,枚举每个数的约数时间复杂度是O(n\(\sqrt{m}\))只有108还是十分可观,我们只需要计数每个数字的次数即可.

Code

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 1e5+10;
int a[N],cnt[N*10],ans[N];
int main()
{
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		cnt[a[i]]++;
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=a[i]/j;j++)
		{
			if(a[i]%j==0) ans[i]+=cnt[j];
			if(a[i]%j==0&&j!=a[i]/j) ans[i]+=cnt[a[i]/j];
		}
		printf("%d\n",ans[i]-1);
	}
	return 0;
}
posted @ 2021-06-01 17:54  acmloser  阅读(44)  评论(0编辑  收藏  举报