链接
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1955
题解
为了方便叙述,我下面的
都是原题中的
每个卦限内情况是一样的,借助对称性可以简化问题
假设
,那么相当于每个点都落在第一卦限中
这样的点的数目是
这个数目直接乘以
加到答案里即可
落在某两个坐标轴所成区域的(即xyz有一个坐标为
),推出来是
这种应该乘以
加进答案
最后,落在坐标轴上的有
个点
上述全部相加,然后输出即可
代码
//推式子
#include <bits/stdc++.h>
#define maxn 100010
#define ll long long
using namespace std;
ll mu[maxn], mark[maxn], prime[maxn], N;
ll read(ll x=0)
{
char c, f=1;
for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-1;
for(;isdigit(c);c=getchar())x=(x<<1)+(x<<3)+c-48;
return f*x;
}
void init()
{
ll i, j;
mu[1]=1;
for(i=2;i<maxn;i++)
{
if(!mark[i])prime[++*prime]=i, mu[i]=-1;
for(j=1;j<=*prime and i*prime[j]<maxn;j++)
{
mark[i*prime[j]]=1;
if(i%prime[j]==0)break;
mu[i*prime[j]]=-mu[i];
}
}
}
void work()
{
ll i, ans=0, t;
for(i=1,N>>=1;i<=N;i++)
{
t=N/i;
ans+=mu[i]*t*t*t*8+mu[i]*t*t*12;
}
ans+=6;
printf("%lld\n",ans);
}
int main()
{
ll kase=0;
init();
while(N=read())printf("Crystal %lld: ",++kase), work();
return 0;
}