[NOI2010]能量采集
【题目分析】
算法一:
位于(x,y)的点产生的分值是:Gcd(x,y);问题转换成求Gcd(x,y)。答案为Σ(gcd(x,y)*2-1),枚举x和y即可以得到80分。时间复杂度O(n^2logn)
算法二:
考虑Gcd(x,y)=D,D<=10^5范围不是很大,那么我们倒过来考虑,我们求解满足Gcd(x,y)=d的(x,y)的个数。
有Σ(gcd(x,y)*2-1)=Σ(F[d]*(d*2-1));其中F[d]表示满足Gcd(x,y)=d的(x,y)的个数。
考虑以d为公约数的(x,y)的个数g[d],显然有g[d]=[n/d]*[m/d];
根据容斥原理有:
f[d]=g[d]-Σ(f[d*i]) (2<=i<=[min(n,m)/d]);
这样我们只需要倒过来从min(n,m)反推到1求解即可。时间复杂度O(nlogn),预计得分100分。
时间复杂度证明:
设L=min(n,m);
Time=Σ(L/i) (1<=i<=L);
Time=LΣ(1/i)<=Lln(L)<=Llog(2,L)
【Code】:
var f:array[0..100001]of int64; ans:int64; n,m,i,j:longint; function min(x,y:longint):longint; begin if x<y then exit(x); exit(y); end; begin 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)); end; writeln(ans); end.
posted on 2011-03-16 13:32 Skywalker_Q 阅读(2612) 评论(0) 收藏 举报