python

时间:2016-04-18 17:57:22

标签: python math

我正在解决SPOJ中的this问题,并指出:

  

问题陈述很简单。给定A和B,你需要计算   S(A,B)。

     

enter image description here

     

这里, 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 我发现enter image description 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

1 个答案:

答案 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功能(返回0gcd(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)