简体   繁体   English

如何减少执行此问题的时间限制

[英]How can I decrease the time limit of execution of this problem

from collections import Counter
def main() :

    n = int(input())
    x1 =tuple(map(int,input().split(' ')))
    n2 = int(input())
    res = []
    memo1 = []
    memo2 = []
    for s1 in range(n2):
        c = 0
        p = list(map(int, input().split(' ')))
        if p in memo1:
            c = memo2[memo1.index(p)]
        else:
            x = x1[p[0]-1 : p[1]]
            y = x1[p[2]-1 : p[3]]
            x = Counter(x)
            y = Counter(y)
            f = x - y
            common = x - f
            g = y - common
            f = f + g
            for v1 in f:
                if v1 in common:
                    c = c + (f[v1]*common[v1])
            for v1 in common:
                c = c + common[v1]**2
            memo1.append(p)
            memo2.append(c)
        res.append(c)
    print(*res,sep='\n')
 main()

It's a program against codeforces.com question这是一个针对codeforces.com 问题的程序

Please suggest me how to solve this...请建议我如何解决这个问题...

Some general pointers:一些通用指针:

  1. Process the input only once, at the start of the program在程序开始时只处理一次输入
  2. Conditions 2 and 3 in the problem statement tell you which indices are valid.问题陈述中的条件 2 和 3 告诉您哪些索引是有效的。 l1 <= i <= r1 and l2 <= j <= r2. l1 <= i <= r1 和 l2 <= j <= r2。 Do not waste time iterating over every possible position in the input list.不要浪费时间遍历输入列表中所有可能的 position。 Only check those indices that would not violate 2 and 3.只检查那些不会违反 2 和 3 的索引。
  3. Pre-processing.预处理。 Condition 1 asks you to verify whether a_i and a_j are equal.条件 1 要求您验证 a_i 和 a_j 是否相等。 You're going to be doing that a lot.你会经常这样做。 So while you are processing the input, keep track (in a map / dictionary) which values are identical.因此,当您处理输入时,请跟踪(在 map / 字典中)哪些值是相同的。 That way it becomes easier to track afterwards.这样以后跟踪就更容易了。

Problem-specific pointers:特定问题的指针:

Look into the disjoint set datastructure.查看不相交的集合数据结构。 It is typically used to quickly evaluate equivalence among objects.它通常用于快速评估对象之间的等效性。 In your case, you could set it up so that it evaluates things like 'i is equivalent to j if a_i equals a_j'.在您的情况下,您可以对其进行设置,以便它评估诸如“如果 a_i 等于 a_j,则 i 等于 j”之类的东西。

Then you can query the datastructure to get all equivalence classes (all indices that point to equal values).然后您可以查询数据结构以获取所有等价类(所有指向相等值的索引)。

Once you have a set of numbers (the indices), you simply need to find all possible pairs of indices that match condition 2 and 3.一旦你有了一组数字(索引),你只需要找到匹配条件 2 和 3 的所有可能的索引对。

I am pretty sure that this problem can easily be solved by Segment Tree .我很确定Segment Tree可以轻松解决这个问题。 I have tried to solve but still unable to pass all test cases.我试图解决但仍然无法通过所有测试用例。
Still, I am posting my solution, if you can optimize it further不过,我正在发布我的解决方案,如果您可以进一步优化它

from collections import Counter

' create segment tree in which each node will contain Counter of values'
def create(current,s,e):
    if s==e:
        tree[current]=Counter([array[s]])
        return tree[current]
    else:
        mid=(s+e)//2
        tree[current]=create(2*current+1,s,mid)+create(2*current+2,mid+1,e)
        return tree[current]

' query elements from l to r and return their counter'
def query(current,s,e,l,r):
    if s>=l and e<=r:
        return tree[current]
    if (r<s and r<e) or (l>s and l>e):
        return Counter()
    mid=(s+e)//2
    return query(2*current+1,s,mid,l,r)+query(2*current+2,mid+1,e,l,r)

n=int(input())
array=list(map(int,input().split( )))
tree=[0]*(4*n+1)
create(0,0,n-1)
#print(tree)
for _ in range(int(input())):
    l1,r1,l2,r2=map(int,input().split( ))
    ans1=query(0,0,n-1,l1-1,r1-1)
    ans2=query(0,0,n-1,l2-1,r2-1)
    ans=0
    for v in ans1:
        ans+=ans1[v]*ans2[v]
    print(ans)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM