本文共 3218 字,大约阅读时间需要 10 分钟。
栋栋有一块长方形的地,他在地上种了一种能量植物,这种植物可以采集太阳光的能量。在这些植物采集能量后,栋栋再使用一个能量汇集机器把这些植物采集到的能量汇集到一起。
栋栋的植物种得非常整齐,一共有 n 列,每列有 m 棵,植物的横竖间距都一样,因此对于每一棵植物,栋栋可以用一个坐标 (x, y) 来表示,其中 x 的范围是 1 至 n,y 的范围是 1 至 m,表示是在第 x 列的第 y 棵。
由于能量汇集机器较大,不便移动,栋栋将它放在了一个角上,坐标正好是 (0, 0)
能量汇集机器在汇集的过程中有一定的能量损失。如果一棵植物与能量汇集机器连接而成的线段上有 k棵植物,则能量的损失为 2k+1。例如,当能量汇集机器收集坐标为 (2, 4) 的植物时,由于连接线段上存在一棵植物 (1, 2),会产生 3 的能量损失。注意,如果一棵植物与能量汇集机器连接的线段上没有植物,则能量损失为 1。现在要计算总的能量损失。
下面给出了一个能量采集的例子,其中 n=5,m = 4,一共有 20 棵植物,在每棵植物上标明了能量汇集机器收集它的能量时产生的能量损失。
在这个例子中,总共产生了 36 的能量损失。
一行两个整数 n,m。
仅包含一个整数,表示总共产生的能量损失。
5 4
36
3 4
20
对于 10 % 10\% 10% 的数据: n , m ≤ 10 n, m \leq 10 n,m≤10
对于 50 % 50\% 50% 的数据: n , m ≤ 100 n, m \leq 100 n,m≤100 对于 80 % 80\% 80% 的数据: n , m ≤ 1 0 3 n, m \leq 10^3 n,m≤103 对于 90 % 90\% 90% 的数据: n , m ≤ 1 0 4 n, m \leq 10^4 n,m≤104 对于 100 % 100\% 100% 的数据: 1 ≤ n , m ≤ 1 0 5 1 \leq n, m \leq 10^5 1≤n,m≤105可以发现一个规律:点 ( x , y ) (x,y) (x,y)的能量损失 = 2 gcd ( x , y ) − 1 =2\gcd(x,y)-1 =2gcd(x,y)−1
因为 ∑ d ∣ i n ∑ d ∣ j m \sum_{d|i}^n\sum_{d|j}^m ∑d∣in∑d∣jm枚举的是 d d d 的倍数 i i i 和 j j j,而1~n中 d d d 的倍数有 ⌊ d n ⌋ ⌊\frac{d}{n}⌋ ⌊nd⌋个,
所以上式中的 i i i 和 j j j 的贡献分别是 ⌊ d n ⌋ ⌊\frac{d}{n}⌋ ⌊nd⌋和 ⌊ d m ⌋ ⌊\frac{d}{m}⌋ ⌊md⌋
式子推出来了,再用就可O(n)解决该题了~~~
#include#include #define Max 1000001using namespace std;long long phi[Max],n,m,p[Max],pn,ans;bool f[Max];void Phi(){ phi[1]=1; for(int i=2;i<=n;i++) { if(!f[i]) { p[++pn]=i; phi[i]=i-1; } for(int j=1;j<=pn&&i*p[j]<=n;j++) { f[i*p[j]]=1; if(i%p[j]==0) { phi[i*p[j]]=phi[i]*p[j]; break; } else phi[i*p[j]]=phi[i]*(p[j]-1); } }}int main(){ scanf("%lld%lld",&n,&m); if(n>m) swap(n,m); Phi(); for(int d=1;d<=n;d++) ans+=phi[d]*(n/d)*(m/d); printf("%lld",(ans<<1)-n*m);}
转载地址:http://ihpwb.baihongyu.com/