题目: | 能量采集 | |
来源: | Noi 2010 day1 第一题 | |
题目大意: | N*M的矩阵中,每个点有一个权值,权值=从(0,0)到达该点所经过的点*2+1,求 矩阵所有点的权值和。 | |
数据范围: | 1 ≤ n, m ≤ 100,000。 | |
样例: | 5 4 | 36 |
做题思路: | 求gcd 然后累加gcd*2-1的话是80分,满分的话需要利用容斥等一系列理论。就是记 录同公约数的个数,并用该个数-它整倍数的个数(叫什么呢,貌似就是因为用的是 公约数而非最大公约数) | |
知识点: | gcd,容斥原理,g[d]=[n/d]*[m/d](以d为公约数的(x,y)的个数 |
var
f:array[0..100010]of int64;{<记录该公约数单独有的数的个数>}
ans:int64;
n,m,i,j:longint;
functionmin(x,y:longint):longint;
begin
if x<y then exit(x);
exit(y);
end;
begin
assign(input,'energy.in');reset(input);
assign(output,'energy.out');rewrite(output);
readln(n,m);
for i:=min(n,m) downto 1 do
begin
f[i]:=int64(n div i)*int64(m div i);{<求有该公约数的数的个数>}
for j:=2 to n div i do dec(f[i],f[i*j]);{<根据容斥,求其单独有的数的个数>}
inc(ans,f[i]*(2*i-1));{<该公约数的个数*(公约数*2-1)即为该公约数对ans的作用>}
end;
writeln(ans);
close(input);close(output);
end.