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))。

我的代码:

 1 var n,m,ans,d:int64;
2 g:longint;
3 f:array[0..100005] of int64;
4 function min(x,y:int64):int64;
5 begin
6 if x<y then min:=x else min:=y;
7 end;
8 begin
9 ans:=0;
10 readln(n,m);
11 for g:=min(n,m) downto 1 do
12 begin
13 f[g]:=(n div g)*(m div g);
14 d:=g+g;
15 while d<=min(n,m) do
16 begin
17 dec(f[g],f[d]);
18 inc(d,g);
19 end;
20 end;
21 for g:=min(n,m) downto 1 do
22 inc(ans,f[g]*(2*g-1));
23 writeln(ans);
24 end.

NOI2010能量采集(数论),布布扣,bubuko.com

时间: 2024-10-27 09:04:07

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 <= n, 1 <= y <= m ) 的数对(x, y)个数. 这个不好求, 考虑容斥, 设f(i) 为含有公因数 i 的数对(x, y)(1 <= x <= n, 1 <= y <= m)个数 , 显然f(i) = (n / i) * (m / i). 则 g(i) = f

BZOJ 2005 NOI2010 能量采集 数论

题目大意:给定n和m,求Σ(1<=i<=n)Σ(1<=j<=m)GCD(i,j)*2-1 i和j的限制不同,传统的线性筛法失效了,这里我们考虑容斥原理 令f[x]为GCD(i,j)=x的数对(i,j)的个数,这个不是很好求 我们令g[x]为存在公因数=x的数对(i,j)的个数(注意不是最大公因数!),显然有g[x]=(n/x)*(m/x) 但是这些数对中有一些的最大公因数为2d,3d,4d,我们要把他们减掉 于是最终f[x]=(n/x)*(m/x)-Σ(2*x<=i*x<

[NOI2010]能量采集

469. [NOI2010]能量采集 ★★☆   输入文件:energy2010.in   输出文件:energy2010.out   简单对比时间限制:1 s   内存限制:512 MB [问题描述] 栋栋有一块长方形的地,他在地上种了一种能量植物,这种植物可以采集太阳光的能量.在这些植物采集能量后,栋栋再使用一个能量汇集机器把这些植物采集到的能量汇集到一起. 栋栋的植物种得非常整齐,一共有n列,每列有m棵,植物的横竖间距都一样,因此对于每一棵植物,栋栋可以用一个坐标(x, y)来表示,其中x

【BZOJ2005】[Noi2010]能量采集 欧拉函数

[BZOJ2005][Noi2010]能量采集 Description 栋栋有一块长方形的地,他在地上种了一种能量植物,这种植物可以采集太阳光的能量.在这些植物采集能量后,栋栋再使用一个能量汇集机器把这些植物采集到的能量汇集到一起. 栋栋的植物种得非常整齐,一共有n列,每列有m棵,植物的横竖间距都一样,因此对于每一棵植物,栋栋可以用一个坐标(x, y)来表示,其中x的范围是1至n,表示是在第x列,y的范围是1至m,表示是在第x列的第y棵. 由于能量汇集机器较大,不便移动,栋栋将它放在了一个角上,

2005: [Noi2010]能量采集

2005: [Noi2010]能量采集 Time Limit: 10 Sec  Memory Limit: 552 MBSubmit: 1831  Solved: 1086[Submit][Status] Description 栋栋有一块长方形的地,他在地上种了一种能量植物,这种植物可以采集太阳光的能量.在这些植物采集能量后,栋栋再使用一个能量汇集机器把这些植物采集到的能量汇集到一起. 栋栋的植物种得非常整齐,一共有n列,每列有m棵,植物的横竖间距都一样,因此对于每一棵植物,栋栋可以用一个坐标

bzoj 2005: [Noi2010]能量采集 筛法||欧拉||莫比乌斯

2005: [Noi2010]能量采集 Time Limit: 10 Sec  Memory Limit: 552 MB[Submit][Status][Discuss] Description 栋栋有一块长方形的地,他在地上种了一种能量植物,这种植物可以采集太阳光的能量.在这些植物采集能量后, 栋栋再使用一个能量汇集机器把这些植物采集到的能量汇集到一起. 栋栋的植物种得非常整齐,一共有n列,每列 有m棵,植物的横竖间距都一样,因此对于每一棵植物,栋栋可以用一个坐标(x, y)来表示,其中x的范

BZOJ 2005 [Noi2010]能量采集 (容斥)

[Noi2010]能量采集 Time Limit: 10 Sec  Memory Limit: 552 MB Submit: 2324  Solved: 1387 [Submit][Status][Discuss] Description 栋栋有一块长方形的地,他在地上种了一种能量植物,这种植物可以采集太阳光的能量.在这些植物采集能量后,栋栋再使用一个能量汇集机器把这些植物采集到的能量汇集到一起. 栋栋的植物种得非常整齐,一共有n列,每列有m棵,植物的横竖间距都一样,因此对于每一棵植物,栋栋可以

2005: [Noi2010]能量采集 - BZOJ

Description 栋栋有一块长方形的地,他在地上种了一种能量植物,这种植物可以采集太阳光的能量.在这些植物采集能量后,栋栋再使用一个能量汇集机器把这些植物采集到的能量汇集到一起. 栋栋的植物种得非常整齐,一共有n列,每列有m棵,植物的横竖间距都一样,因此对于每一棵植物,栋栋可以用一个坐标(x, y)来表示,其中x的范围是1至n,表示是在第x列,y的范围是1至m,表示是在第x列的第y棵. 由于能量汇集机器较大,不便移动,栋栋将它放在了一个角上,坐标正好是(0, 0). 能量汇集机器在汇集的过

【BZOJ 2005】[Noi2010]能量采集

Description 栋栋有一块长方形的地,他在地上种了一种能量植物,这种植物可以采集太阳光的能量.在这些植物采集能量后,栋栋再使用一个能量汇集机器把这些植物采集到的能量汇集到一起. 栋栋的植物种得非常整齐,一共有n列,每列有m棵,植物的横竖间距都一样,因此对于每一棵植物,栋栋可以用一个坐标(x, y)来表示,其中x的范围是1至n,表示是在第x列,y的范围是1至m,表示是在第x列的第y棵. 由于能量汇集机器较大,不便移动,栋栋将它放在了一个角上,坐标正好是(0, 0). 能量汇集机器在汇集的过