目录
1.介绍
(同上,教练把lg禁了,暂时给不了网址+还我LG!!!)
怎么说呢,弱化forest (forest网址下次补上)
就这一个弱化,就从莫比乌斯反演 欧拉函数
2.分析
看一看图片
其实我们可以沿着对角线就是一下
把它变成
、
与
(截屏截的好丑呀qwq)
实际上,我们只需要求 的总数给它乘二加三(因为有(1,0),(1,1),(0,1))即可
问题又来了: 怎么求?
举个例子:坐标(2,4)的人会被坐标 (1,2)的人挡住,坐标(4,2)的人会被(2,1)的人挡住
简单猜测分析一下就知道:(x,y)中(x,y)互质就不会被挡住
所以求出一半的图中坐标(x,y)互质的就行了
但你暴力的话,行 会变成 刑
所以只能优化。
对于每个 我们需要统计有多少个 x 满足
并且 gcd(x,y)=1 。这样的 x 的数量恰好就是
。
累计求和就行
(哦,对了,记得特判 n=1 ,不然你就孤芳自赏了 doge)
3.代码
1.有注释版
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;//小心爆掉
ll n;//题目要求
ll ans;//总和
ll e[40010];//欧拉
int main()
{
cin>>n;//输入
ans=2;//特判
for(int i=1;i<=n;i++)//循环赋初值
e[i]=i;//赋初值
for(int i=2;i<=n;i++)//筛
if(e[i]==i)
for(int j=i;j<=n;j+=i) e[j]=e[j]/i*(i-1);
for(int i=2;i<n;++i) ans+=e[i]*2;//*2
if(n==1) ans=-1;//特判
printf("%lld",ans+1);//还是特判
return 0;//返回
}//欧耶!
2.copy 专用
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,ans,e[40010];
int main()
{
cin>>n;
ans=2;
for(int i=1;i<=n;i++) e[i]=i;
for(int i=2;i<=n;i++)
if(e[i]==i)
for(int j=i;j<=n;j+=i) e[j]=e[j]/i*(i-1);
for(int i=2;i<n;++i) ans+=e[i]*2;
if(n==1) ans=-1;
printf("%lld",ans+1);
return 0;
}
(完结撒花!)