NOI2010能量采集(数论)
没想到NOI竟然还有这种数学题,看来要好好学数论了……
网上的题解:
完整的结题报告:
首先我们需要知道一个知识,对于坐标系第一象限任意的整点(即横纵坐标均为整数的点)p(n,m),其与原点o(0,0)的连线上除过原点整点的个数为gcd(n,m)。其他象限上个数则为gcd(abs(n),abs(m)),这里的gcd(a,b)是指a与b的最大公约数(Greastest Common Divisor),abs(a)是指数a的绝对值。
证明:
考虑在op上最小的一个整点(x,y),这里的最小是指横纵坐标绝对值最小,x与y必然满足gcd(x,y)=1,即x与y互质。因为若不互质的话,将x与y均除去他们的公约数后可以产生一个更小的整点。则显然有(kx,ky){x<=kx<=n,k属于正整数}也在线段op上,而且这些点也是op上全部的整点,显然这些点的个数等于最大的那个k。为方便叙述我们直接将其称为k,其满足kx=n,ky=m。则显然k=gcd(n,m),证明完毕。
则现在我们只需要求出每一个gcd(n,m)即可,这里我们可以使用经典的欧几里德算法,其的复杂度为O(lgb),b为两个数中较小的那个。总的复杂度将为O(n^2lgn)但是考虑到此题的规模极大,此方法必然超时。
进一步考虑,我们不难发现要求的最大公约数的规模相对于所有数对的规模要小的多。所以我们可以转而求对于一个数p(p<min(n,m)),满足gcd(a,b)=p的数对(a,b)的个数。
令num[i]表示最大公约数为i的数对的个数,bound为min(n,m)。首先可以知道公约数有i的数对的个数应为(n div i)*(m div i),这个是比较好想的,然而并没有满足要求,因为i并不为最大公约数。不过处理方法很简单,考虑到这些当前的数对可能存在比i更大的公约数为2i,3i,4i...ki(ki<=bound),只需将这些数对删去即可。
这样我们就有了整体框架,首先可以直接求出num[bound] = (n div bound)*(m div bound),按照从大到小的顺序求num[i]即可,num[i] = (n div i)*(m div i)-Sigma(num[ki]) , 1<=ki<=bound) (那个求和的符号我打不出来...)
则代价的总和为2*Sigma(num[i]*i)-nm(因为题目中要求的线段上的整点不包括端点,而我们算的gcd(a,b),其中包括了点(a,b))。
我的代码:
var n,m,ans,d:int64;
g:longint;
f:array[..] of int64;
function min(x,y:int64):int64;
begin
if x<y then min:=x else min:=y;
end;
begin
ans:=;
readln(n,m);
for g:=min(n,m) downto do
begin
f[g]:=(n div g)*(m div g);
d:=g+g;
while d<=min(n,m) do
begin
dec(f[g],f[d]);
inc(d,g);
end;
end;
for g:=min(n,m) downto do
inc(ans,f[g]*(*g-));
writeln(ans);
end.
ps:f[i]:=(n div i )* (m div i)
在这个式子中,即使 f 数组为 int64 数组,但n,m为 longint ,当n=m=100000时还是会发生溢出,所以n,m也必为 inf64
这种容易忽视的错误需要注意,即参与四则运算的变量必须能承载运算结果!
UPD:更简单的莫比乌斯反演
sigma(gcd(x,y))1<=x<=n,1<=y<=m=sigma(fai[k]*(n/k)*(m/k)) 1<=k<=min(n,m)
线性筛就行了。
代码:
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<string>
#define inf 1000000000
#define maxn 100000+5
#define maxm 100000+5
#define eps 1e-10
#define ll long long
#define pa pair<int,int>
#define for0(i,n) for(int i=0;i<=(n);i++)
#define for1(i,n) for(int i=1;i<=(n);i++)
#define for2(i,x,y) for(int i=(x);i<=(y);i++)
#define for3(i,x,y) for(int i=(x);i>=(y);i--)
#define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
#define mod 1000000007
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=*x+ch-'';ch=getchar();}
return x*f;
}
ll n,m,p[maxn],tot,fai[maxn];
ll ans;
bool v[maxn];
inline void get()
{
fai[]=;
for2(i,,m)
{
if(!v[i])p[++tot]=i,fai[i]=i-;
for1(j,tot)
{
int k=p[j]*i;
if(k>m)break;
v[k]=;
if(i%p[j])fai[k]=fai[i]*(p[j]-);
else {fai[k]=fai[i]*p[j];break;}
}
}
}
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
n=read();m=read();
if(n<m)swap(n,m);
get();
for1(i,m)ans+=fai[i]*(n/i)*(m/i);
cout<<n*m+*(ans-n*m)<<endl;
return ;
}
NOI2010能量采集(数论)的更多相关文章
- BZOJ 2005: [Noi2010]能量采集( 数论 + 容斥原理 )
一个点(x, y)的能量损失为 (gcd(x, y) - 1) * 2 + 1 = gcd(x, y) * 2 - 1. 设g(i)为 gcd(x, y) = i ( 1 <= x <= ...
- Luogu P1447 [NOI2010]能量采集 数论??欧拉
刚学的欧拉反演(在最后)就用上了,挺好$qwq$ 题意:求$\sum_{i=1}^{N}\sum_{j=1}^{M}(2*gcd(i,j)-1)$ 原式 $=2*\sum_{i=1}^{N}\sum_ ...
- [BZOJ2005][Noi2010]能量采集 容斥+数论
2005: [Noi2010]能量采集 Time Limit: 10 Sec Memory Limit: 552 MBSubmit: 4394 Solved: 2624[Submit][Statu ...
- BZOJ 2015:[Noi2010]能量采集(数论+容斥原理)
2005: [Noi2010]能量采集 Description 栋栋有一块长方形的地,他在地上种了一种能量植物,这种植物可以采集太阳光的能量.在这些植物采集能量后,栋栋再使用一个能量汇集机器把这些植物 ...
- BZOJ 2005 [Noi2010]能量采集 (数学+容斥 或 莫比乌斯反演)
2005: [Noi2010]能量采集 Time Limit: 10 Sec Memory Limit: 552 MBSubmit: 4493 Solved: 2695[Submit][Statu ...
- luogu1447 [NOI2010]能量采集 莫比乌斯反演
link 冬令营考炸了,我这个菜鸡只好颓废数学题了 NOI2010能量采集 由题意可以写出式子: \(\sum_{i=1}^n\sum_{j=1}^m(2\gcd(i,j)-1)\) \(=2\sum ...
- BZOJ 2005: [Noi2010]能量采集
2005: [Noi2010]能量采集 Time Limit: 10 Sec Memory Limit: 552 MBSubmit: 3312 Solved: 1971[Submit][Statu ...
- noi2010 能量采集
2005: [Noi2010]能量采集 Time Limit: 10 Sec Memory Limit: 552 MB Submit: 3068 Solved: 1820 [Submit][Sta ...
- bzoj2005: [Noi2010]能量采集
lsj师兄的题解 一个点(x, y)的能量损失为 (gcd(x, y) - 1) * 2 + 1 = gcd(x, y) * 2 - 1. 设g(i)为 gcd(x, y) = i ( 1 < ...
- 2005: [Noi2010]能量采集
2005: [Noi2010]能量采集 Time Limit: 10 Sec Memory Limit: 552 MBSubmit: 1831 Solved: 1086[Submit][Statu ...
随机推荐
- 35 个必须有的Bootstrap工具和生成器
Bootstraptor If you think that bootstrap templates are not enough for you, you should go with bootst ...
- Demo学习: CustomException
CustomException 捕获程序发生的异常. 1. 抛出各种异常 procedure TMainForm.UniButton1Click(Sender: TObject); begin PBy ...
- hadoop中遇到的问题。
1.物理主机中无法访问管理界面,在虚拟主机中可以访问, 这跟防火墙有关系,重启一下防火墙,然后关闭,最后重启一下handoop,应该就可以了!!!!(hadoop首战顺利!!!!!(●'◡'●))
- wpf 绑定失效的原因及解决方案
有时候,您会发现在程序开始时还能正常运行的绑定失效了.就个人经验而言,绑定的失效主要分为两种情况:对于One-way绑定而言,如果软件开发人员绕过绑定直接更改了目标属性,那么绑定将会失效.而对于Two ...
- EXTJS 4.2 资料 控件之Grid 添加行,编辑行,删除行
//SiteVariableConfigValue类,创立一个模型类 Ext.define("SiteVariableConfigValue", { extend: "E ...
- 类的本质、description方法、SEL、NSLog输出增强
一.类的本质 1.类也是个对象 其实类也是一个对象,是Class类型的对象,简称“类对象” Class类型的定义 typedef struct objc_class *Class; 类名就代表着类对象 ...
- python 新时代
今天看到有关python的文章,感觉很好奇,学了python很久了,但是还没有真正的用过,只是写一些小程序 看了这篇文章以后真的感觉自己所了解都是皮毛,在此与大家分享: 原文链接:http://www ...
- poj 3207 Ikki's Story IV - Panda's Trick (2-SAT)
http://poj.org/problem?id=3207 Ikki's Story IV - Panda's Trick Time Limit: 1000MS Memory Limit: 13 ...
- phpd读取txt文件(自动解析换行)
<form id="form" method="post" action="whois.php"> <?php $newf ...
- 1052: [HAOI2007]覆盖问题 - BZOJ
Description 某人在山上种了N棵小树苗.冬天来了,温度急速下降,小树苗脆弱得不堪一击,于是树主人想用一些塑料薄膜把这些小树遮盖起来,经过一番长久的思考,他决定用3个L*L的正方形塑料薄膜将小 ...