QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#113360#5466. Permutation CompressionkemunikuTL 24ms9544kbPython36.0kb2023-06-17 10:37:302023-06-17 10:37:33

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-06-17 10:37:33]
  • 评测
  • 测评结果:TL
  • 用时:24ms
  • 内存:9544kb
  • [2023-06-17 10:37:30]
  • 提交

answer

# https://github.com/tatyam-prime/SortedSet/blob/main/SortedSet.py
import math
from bisect import bisect_left, bisect_right
from typing import Generic, Iterable, Iterator, TypeVar, Union, List
T = TypeVar('T')

class SortedSet(Generic[T]):
    BUCKET_RATIO = 50
    REBUILD_RATIO = 170

    def _build(self, a=None) -> None:
        "Evenly divide `a` into buckets."
        if a is None: a = list(self)
        size = self.size = len(a)
        bucket_size = int(math.ceil(math.sqrt(size / self.BUCKET_RATIO)))
        self.a = [a[size * i // bucket_size : size * (i + 1) // bucket_size] for i in range(bucket_size)]
    
    def __init__(self, a: Iterable[T] = []) -> None:
        "Make a new SortedSet from iterable. / O(N) if sorted and unique / O(N log N)"
        a = list(a)
        if not all(a[i] < a[i + 1] for i in range(len(a) - 1)):
            a = sorted(set(a))
        self._build(a)

    def __iter__(self) -> Iterator[T]:
        for i in self.a:
            for j in i: yield j

    def __reversed__(self) -> Iterator[T]:
        for i in reversed(self.a):
            for j in reversed(i): yield j
    
    def __len__(self) -> int:
        return self.size
    
    def __repr__(self) -> str:
        return "SortedSet" + str(self.a)
    
    def __str__(self) -> str:
        s = str(list(self))
        return "{" + s[1 : len(s) - 1] + "}"

    def _find_bucket(self, x: T) -> List[T]:
        "Find the bucket which should contain x. self must not be empty."
        for a in self.a:
            if x <= a[-1]: return a
        return a

    def __contains__(self, x: T) -> bool:
        if self.size == 0: return False
        a = self._find_bucket(x)
        i = bisect_left(a, x)
        return i != len(a) and a[i] == x

    def add(self, x: T) -> bool:
        "Add an element and return True if added. / O(√N)"
        if self.size == 0:
            self.a = [[x]]
            self.size = 1
            return True
        a = self._find_bucket(x)
        i = bisect_left(a, x)
        if i != len(a) and a[i] == x: return False
        a.insert(i, x)
        self.size += 1
        if len(a) > len(self.a) * self.REBUILD_RATIO:
            self._build()
        return True

    def discard(self, x: T) -> bool:
        "Remove an element and return True if removed. / O(√N)"
        if self.size == 0: return False
        a = self._find_bucket(x)
        i = bisect_left(a, x)
        if i == len(a) or a[i] != x: return False
        a.pop(i)
        self.size -= 1
        if len(a) == 0: self._build()
        return True
    
    def lt(self, x: T) -> Union[T, None]:
        "Find the largest element < x, or None if it doesn't exist."
        for a in reversed(self.a):
            if a[0] < x:
                return a[bisect_left(a, x) - 1]

    def le(self, x: T) -> Union[T, None]:
        "Find the largest element <= x, or None if it doesn't exist."
        for a in reversed(self.a):
            if a[0] <= x:
                return a[bisect_right(a, x) - 1]

    def gt(self, x: T) -> Union[T, None]:
        "Find the smallest element > x, or None if it doesn't exist."
        for a in self.a:
            if a[-1] > x:
                return a[bisect_right(a, x)]

    def ge(self, x: T) -> Union[T, None]:
        "Find the smallest element >= x, or None if it doesn't exist."
        for a in self.a:
            if a[-1] >= x:
                return a[bisect_left(a, x)]
    
    def __getitem__(self, x: int) -> T:
        "Return the x-th element, or IndexError if it doesn't exist."
        if x < 0: x += self.size
        if x < 0: raise IndexError
        for a in self.a:
            if x < len(a): return a[x]
            x -= len(a)
        raise IndexError
    
    def index(self, x: T) -> int:
        "Count the number of elements < x."
        ans = 0
        for a in self.a:
            if a[-1] >= x:
                return ans + bisect_left(a, x)
            ans += len(a)
        return ans

    def index_right(self, x: T) -> int:
        "Count the number of elements <= x."
        ans = 0
        for a in self.a:
            if a[-1] > x:
                return ans + bisect_right(a, x)
            ans += len(a)
        return ans

import heapq


def solve():
    N,M,K = map(int,input().split())
    A = list(map(int,input().split()))
    B = list(map(int,input().split()))
    L = list(map(int,input().split()))
    rB = list(reversed(B))
    for i in range(N):
        if A[i] == rB[-1]:
            rB.pop()
        if len(rB) == 0:
            break
    if len(rB) != 0:
        return "NO"
    sB = set(B)
    ok = [-1]*N
    q = []
    v_to_i = [-1]*(N+1)
    for i in range(N):
        v_to_i[A[i]] = i
    #右の値をまず計算する
    start = [-1]*(N+1)
    st = SortedSet()
    for i in range(N-1,-1,-1):
        if A[i] in sB:#赤い数なら
            while len(q) != 0 and q[0] < A[i]:
                x = heapq.heappop(q)
                ok[v_to_i[x]] = st.index(x)-start[x]
        else:
            heapq.heappush(q,A[i])
            start[A[i]]  = st.index(A[i])
        st.add(A[i])
    while len(q) != 0:
        x = heapq.heappop(q)
        ok[v_to_i[x]] = st.index(x)-start[x]
    #次に左の値を計算する
    q = []
    start = [-1]*(N+1)
    st = SortedSet()
    for i in range(N):
        if A[i] in sB:#赤い数なら
            while len(q) != 0 and q[0] < A[i]:
                x = heapq.heappop(q)
                ok[v_to_i[x]] += st.index(x)-start[x]
        else:
            heapq.heappush(q,A[i])
            start[A[i]]  += st.index(A[i])
        st.add(A[i])
    while len(q) != 0:
        x = heapq.heappop(q)
        ok[v_to_i[x]] += st.index(x)-start[x]
    li = sorted([ok[i] for i in range(N) if ok[i] != -1])
    if len(li) > len(L):
        return "NO"
    L.sort()
    for i in range(len(li)):
        if li[i] < L[i]:
            return "NO"
    return "YES"

for i in range(int(input())):
    print(solve())

详细

Test #1:

score: 100
Accepted
time: 12ms
memory: 9544kb

input:

3
5 2 3
5 1 3 2 4
5 2
1 2 4
5 5 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
3 2 2
3 1 2
3 2
2 3

output:

YES
YES
NO

result:

ok 3 lines

Test #2:

score: 0
Accepted
time: 19ms
memory: 9484kb

input:

100
2 1 2
2 1
2
1 1
2 1 2
1 2
1
2 2
2 1 1
1 2
1
2
6 1 5
3 4 2 5 6 1
3
5 2 1 1 1
6 1 6
2 1 3 6 4 5
1
4 1 2 2 1 4
3 3 2
2 1 3
2 1 3
2 2
1 1 1
1
1
1
1 1 1
1
1
1
2 1 2
2 1
2
1 2
4 4 3
2 1 3 4
2 1 3 4
4 3 1
1 1 1
1
1
1
6 5 1
6 2 5 4 3 1
6 2 4 3 1
4
1 1 1
1
1
1
6 5 3
3 6 1 4 5 2
3 6 1 4 2
3 3 4
4 3 4
3 4 ...

output:

YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
NO
YES
YES
YES
YES
NO
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
NO
NO
NO
YES
YES
NO
NO
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
NO
YES
YES
YES
YES
YES
YES
NO
YES
YES
YES
YES
YES
YES
YES
NO
YES
YES
YES
YES
YE...

result:

ok 100 lines

Test #3:

score: 0
Accepted
time: 24ms
memory: 9520kb

input:

99
6 1 6
1 5 3 4 2 6
1
1 2 1 1 1 6
1 1 1
1
1
1
4 1 3
3 4 1 2
1
1 1 2
2 2 1
2 1
2 1
2
1 1 1
1
1
1
2 1 2
1 2
2
1 2
1 1 1
1
1
1
1 1 1
1
1
1
3 2 2
3 2 1
2 1
1 2
3 3 1
2 3 1
2 3 1
1
6 1 5
3 4 2 5 6 1
3
4 2 1 1 1
6 4 4
1 6 5 2 3 4
1 2 3 4
5 4 4 6
2 1 1
1 2
1
1
6 5 1
2 1 4 5 6 3
2 1 4 6 3
2
6 3 6
5 6 2 1 3...

output:

YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
NO
NO
YES
YES
YES
YES
YES
YES
YES
YES
YES
NO
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
NO
YES
YES
YES
YES
YES
YES
YES
NO
NO
YES
YES
YES
NO
YES
YES
YES
NO
YES
YES
NO
YES
NO
YES
NO
YES
YES
YES
YES
YES
YES
NO
YES
NO
NO
YES
YES
YES
YE...

result:

ok 99 lines

Test #4:

score: 0
Accepted
time: 18ms
memory: 9512kb

input:

98
6 1 6
6 1 4 5 2 3
3
1 2 2 1 1 6
4 3 2
2 3 4 1
2 1 3
3 4
1 1 1
1
1
1
6 1 6
6 4 3 1 2 5
1
3 1 3 1 1 5
1 1 1
1
1
1
6 4 4
3 4 1 2 5 6
3 4 1 2
2 4 3 1
6 5 1
4 5 3 6 1 2
4 5 3 1 2
6
1 1 1
1
1
1
5 1 4
1 3 2 4 5
1
5 3 4 4
6 3 4
1 4 2 3 6 5
1 2 5
5 4 6 5
4 1 3
2 1 4 3
2
1 1 1
1 1 1
1
1
1
6 3 5
5 1 3 6 4 2...

output:

YES
NO
YES
YES
YES
YES
YES
YES
NO
NO
YES
YES
NO
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
NO
YES
YES
YES
NO
YES
YES
YES
NO
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
NO
YES
YES
YES
YES
NO
YES
YES
YES
YES
YES
NO
YES
NO
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
NO
YES
NO
Y...

result:

ok 98 lines

Test #5:

score: -100
Time Limit Exceeded

input:

60000
1 1 1
1
1
1
1 1 1
1
1
1
3 2 1
2 3 1
2 1
2
3 3 1
1 2 3
1 2 3
1
1 1 1
1
1
1
1 1 1
1
1
1
1 1 1
1
1
1
3 3 2
3 2 1
3 2 1
1 1
2 2 1
2 1
2 1
1
1 1 1
1
1
1
2 2 1
1 2
1 2
1
1 1 1
1
1
1
3 1 3
2 3 1
1
2 3 2
3 3 2
2 3 1
2 3 1
2 1
1 1 1
1
1
1
1 1 1
1
1
1
1 1 1
1
1
1
3 2 3
3 2 1
2 1
1 2 1
3 2 2
1 3 2
3 2
3 ...

output:

YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
NO
YES
YES
YES
YES
YES
YES
NO
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
NO
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES...

result: