我正在解决SPOJ中的this问题,并指出:
问题陈述很简单。给定A和B,你需要计算 S(A,B)。
这里, f(n)= n,如果n是平方自由,否则为0.另外f(1)= 1 。
输入
第一行包含一个整数 T - 表示测试次数 例。
每个T 行包含两个整数 A,B 。
输出
对于每个测试用例输出,S中的S(A,B)mod 1000000007的值 单行。
约束
`T <= 1000 1 <= A,B <= 1000000`
实施例
Input: 3 42 18 35 1 20 25 Output: 306395 630 128819
我为这个问题编写了这段代码(如果我遇到了问题):
def gcd(a,b): #gcd(a,b)
if b==0:
return a
else:
return gcd(b,a%b)
# print gcd(42,18)
import math
def issquarefree(n): #sqare free number check
i=2
s=i*i
if (n==1 or n==2) or n==3:
return True
while s<=n:
if n%s==0:
i=-1
break
else:
i+=1
s=i*i
if i==-1:return False
else:
return True
for i in range(int(raw_input())): #main program
a,b=map(int,raw_input().split())
g=gcd(a,b)
sa=(a*(a+1))/2 #see below
sb=(b*(b+1))/2 #see below
gc=issquarefree(g)
s=0
if gc== False:
print 0
elif gc==True:
s+=sa*sb*g
print s%1000000007
here 我发现所以将此问题应用于问题#S(A,B)我把它写成(第一个A和B数之和的乘法)乘以f(n)这是gcd(a,b)或0。
但我没有得到这个问题的预期输出,所以我的代码错了或者我的问题出错了
我的输出与预期
3
35 1
42 18
20 25
630 630
926478 306395
341250 128819
答案 0 :(得分:1)
写出G(a, b) = f(gcd(a, b))
(这样你可以使用引用的公式)是不正确的,因为函数不是常数。正确的解决方案是:
for i in range(int(raw_input())):
A, B = map(int, raw_input().split())
# proper algorithm
s = 0
for a in xrange(1, A):
for b in xrange(1, B):
s += a * b * G(a, b)
print s % 1000000007
您显然必须正确实施G
功能(返回0
或gcd(a, b)
)。
对G
进行仔细分析可能会给出一些优化见解,但如果有的话,这绝对不是一件小事。
这是一个简单的优化:
import fractions
DIVISOR = 1000000007
def is_not_square_free(a):
counter = 1
factor = 1
while factor < a:
counter += 1
factor = counter * counter
if a % factor == 0:
return True
return factor == a
def F(n):
if n == 1:
return 1
if is_not_square_free(n):
return 0
return n
_CACHE = {}
def G(a, b):
a = a % DIVISOR
b = b % DIVISOR
key = (a, b) if a > b else (b, a)
if key not in _CACHE:
_CACHE[key] = (a * b * F(fractions.gcd(a, b))) % DIVISOR
return _CACHE[key]
def S(A, B):
s = 0
for a in range(1, A+1):
for b in range(1, B+1):
s += G(a, b)
return s
for _ in range(int(raw_input())):
A, B = map(int, raw_input().split())
print(S(A, B) % DIVISOR)