[CSP-S模拟测试]:玄学题/c(数学)

题目传送门(内部题40)


输入格式

第一行:两个正整数$n$、$m$。


输出格式

第一行:一个整数,代表式子的值。


样例

样例输入1:

4 5

样例输出1:

0
样例输入2:

799 8278

样例输出2:

-11


数据范围与提示


题解

对于每个$i$,其对答案的贡献就是它能与$1\sim m$中的几个数相乘得到完全平方数。

显然我们需要枚举$i$,然后$\Theta(1)$算贡献。

所以这时候就存在两种情况:

  $\alpha.i$是完全平方数,这时候我们只需要求出$1\sim m$中有几个完全平方数,而这个数就是$\sqrt m$。

  $\beta.i$不是完全平方数,众所周知,完全平方数$\times$完全平方数$=$完全平方数。那么考虑分解$i$,将其分解成$p_1\times p_2\times ...\times q$,其中$p$为完全平方数,$q$为非完全平方数,我们需要求的是$q\times j$有几个是完全平方数,而这个数即为$\sqrt{\frac{m}{q}}$。

预处理出来每一个$i$的$q$,即可$\Theta(1)$算贡献。

时间复杂度:$\Theta(n)$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include<bits/stdc++.h>
using namespace std;
int n;
long long m;
int cnt[10000001];
bool pfs[10000001];
int ans;
int main()
{
	scanf("%d%lld",&n,&m);
	for(int i=1;i*i<=n;i++)
	{
		for(int j=1;i*i*j<=n;j++)
			cnt[i*i*j]=j;
		pfs[i*i]=1;
	}
	int sqr=sqrt(m);
	for(int i=1;i<=n;i++)
		if(pfs[i])
		{
			if(sqr&1)ans--;
			else ans++;
		}
		else
		{
			if((int)sqrt(m/cnt[i])&1)ans--;
			else ans++;
		}
	printf("%d",ans);
	return 0;
}

rp++

posted @ 2019-09-10 17:42  HEOI-动动  阅读(283)  评论(0编辑  收藏  举报