You are given N numbers. Now you have Q queries. For each query you will be given an integer K
Input Format The first line consists of number N. Next N line contains N numbers. Next line contains number of queries Q. Next Q lines contains Integer K for each query
Output Format Output Q lines the answer for every query.
Constraints 1 <= N <= 10^5; 1 <= numbers <= 10^5; 1 <= Q <= 10^5; 1 <= K <= 10^5
Sample Input
4 5 8 10 8 1 2
Sample Output
3
我的代码,得到一个使用78000个输入的失败测试用例:
ans = []
def countSieve(arr, n):
MAX=max(arr)
global ans
ans = [0]*(MAX + 1)
cnt = [0]*(MAX + 1)
for i in range(n):
cnt[arr[i]] += 1
for i in range(1, MAX+1):
for j in range(i, MAX+1, i):
ans[i] += cnt[j]
def countMultiples(k):
return(ans[k])
n=int(input())
a=[]
count=0
for i in range(n):
j=int(input())
a.append(j)
countSieve(a,n)
q=int(input())
k=[]
for i in range(q):
c=int(input())
k.append(c)
i=0
for i in k:
print(countMultiples(i))
问题是您创建了一个大小为
MAX(a)
的数组,其中a
是您的n
编号列表。例如,如果MAX(a) = 10^5
,这是低效的您应该找到另一种方法来检查数字a是否是数字B的倍数,例如
A%B == 0
(使用模)尝试删除
countSieve
并更改countMultiples
编辑:
这里有一个优化。首先我搜索数字除数,对于每个除数,我在dict
d
中增加一个计数器,然后对于查询q
I printd[q]
,这是n个数字中存在的倍数的确切数量搜索数
n
的除数的方法是:我做一个循环,直到n
的平方根,然后对于每个除数i
,我还加上r = n//i
我还使用dict
divs
来存储每个数字n的除数,以便在我已经找到它们时不会重新计算它们试试这个(它成功地解决了问题https://hack.codingblocks.com/app/dcb/938):
或者,您可以尝试计算每个数字出现的频率,然后检查
k
的每个倍数的计数,直到N个数字中的最大值乍一看,这与其他方法没有太大区别,我认为理论上这甚至还有O(N*Q),但对于Q的大值,这应该会有很大的提升
假设Q=100000。对于所有K>;10(即除K的10个值外的所有值)您最多只需检查10000个倍数(因为
m <= 100,000
)。对于所有K>;10000(即90%的可能值)您只需检查最多10个倍数,对于50%的Ks,只需检查K本身换句话说,除非我的逻辑有错误,在N=Q=100000的最坏情况下,你只有110万张支票,而不是1000000000
(这假设所有K都不同,但如果不是,则可以将结果缓存在dict中,然后也只需要对重复项进行一次检查。)
仔细观察,这种方法实际上非常类似于您的筛子所做的,只是更加紧凑,根据需要计算每个
k
的值,而不是一次计算所有值我使用
gen_input(n, q, max_k)
的随机输入做了一些时序分析。首先,所有算法似乎产生相同的结果。对于较小的输入大小,在速度上没有显著差异(除了朴素的模),并且您的原始筛确实是最快的。对于较大的输入(最大值),您的输入仍然是最快的(甚至是更大的幅度),而divisors
方法的速度要慢得多不知道为什么在@phoenixo的
divisors
据称有效时,你和我的算法会超时(不过没有尝试过)相关问题 更多 >
编程相关推荐