Loading

加载过慢可尝试刷新

【题解】洛谷 SP3591 PATHEADS - Patting Heads 题解

洛谷题目传送门 | SP 原题传送门

本题双倍经验,同主题库P2926

思路

又是一道桶的题。

首先暴力,对于 \(N=100000\),复杂度 \(O(n^2)\),显然超时。

考虑优化。

看题面,不难想到用桶记录每个数字的出现次数,只需要遍历数组找到比 \(a_i\) 小的数即可。

但是这样仍然超时,继续优化。发现遍历数组时没必要全遍历一边,只需要遍历到 \(\sqrt{n}\) 即可。

注意以下几点:

  1. 对于完全平方数,\(\sqrt{n}\) 会计算两遍,此时答案数减一;

  2. 奶牛会拍到自己的头,答案数还需要减一。

然后就可以看见一篇绿色了。

代码

#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
inline int read()
{
	int s=0,w=1;
	char ch=getchar();
	while(ch<'0' || ch>'9'){if(ch=='-')w=-1;ch=getchar();}
	while(ch>='0' && ch<='9') s=s*10+ch-'0',ch=getchar();
	return s*w;
}
const int N=1e5+10;
int n,ans=0;
int a[N],t[1000010];
int main()
{
	n=read();
	for(int i=1;i<=n;i++)
	{
		a[i]=read();
		t[a[i]]++;
	}
	for(int i=1;i<=n;i++)
	{
		ans=0;
		for(int j=1;j<=sqrt(a[i]);j++)
		{
			if(a[i]%j==0)
			{
				ans+=t[j]+t[a[i]/j];
				if(j*j==a[i])
				{
					ans-=t[j];
				}
			}
		}
		cout<<ans-1<<endl;
	}
	return 0;
}
posted @ 2022-07-10 22:01  Makerlife  阅读(26)  评论(0)    收藏  举报