[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++