Submission details
Task:Hypyt
Sender:MaksimMoz
Submission time:2025-11-09 12:53:40 +0200
Language:Python3 (CPython3)
Status:READY
Result:60
Feedback
groupverdictscore
#1ACCEPTED10
#2ACCEPTED20
#3ACCEPTED15
#4ACCEPTED15
#50
Test results
testverdicttimegroup
#1ACCEPTED0.02 s1, 2, 3, 4, 5details
#2ACCEPTED0.02 s1, 2, 3, 4, 5details
#3ACCEPTED0.02 s1, 2, 3, 4, 5details
#4ACCEPTED0.02 s1, 2, 3, 4, 5details
#5ACCEPTED0.02 s1, 2, 3, 4, 5details
#6ACCEPTED0.08 s2, 5details
#7ACCEPTED0.06 s2, 5details
#8ACCEPTED0.04 s2, 5details
#9ACCEPTED0.59 s3, 4, 5details
#10ACCEPTED0.61 s3, 4, 5details
#11ACCEPTED0.63 s3, 4, 5details
#12ACCEPTED0.61 s4, 5details
#13ACCEPTED0.63 s4, 5details
#14ACCEPTED0.63 s4, 5details
#15ACCEPTED0.70 s5details
#16ACCEPTED0.69 s5details
#17ACCEPTED0.69 s5details
#18ACCEPTED0.68 s5details
#19--5details
#20--5details
#21--5details
#22ACCEPTED0.02 s1, 2, 3, 4, 5details
#23ACCEPTED0.02 s1, 2, 3, 4, 5details
#24ACCEPTED0.29 s5details
#25ACCEPTED0.28 s5details
#26ACCEPTED0.69 s5details
#27ACCEPTED0.28 s5details

Code

import sys
from collections import deque


class DSU:
    __slots__ = ("p", "sz")
    def __init__(self, n):
        self.p = list(range(n))
        self.sz = [1]*n
    def find(self, x):
        p = self.p
        while p[x] != x:
            p[x] = p[p[x]]
            x = p[x]
        return x
    def union(self, a, b):
        a = self.find(a); b = self.find(b)
        if a == b: return
        if self.sz[a] < self.sz[b]: a, b = b, a
        self.p[b] = a
        self.sz[a] += self.sz[b]


def or_rows_to_cols(rows_mask, row_masks):

    res = 0
    rm = rows_mask
    while rm:
        lb = rm & -rm
        r = lb.bit_length() - 1
        res |= row_masks[r]
        rm ^= lb
    return res

def or_cols_to_rows(cols_mask, col_masks):

    res = 0
    cm = cols_mask
    while cm:
        lb = cm & -cm
        c = lb.bit_length() - 1
        res |= col_masks[c]
        cm ^= lb
    return res


def main():
    data = sys.stdin.buffer.read().split()
    it = iter(data)
    n = int(next(it)); m = int(next(it)); q = int(next(it))

    N = n + m
    dsu = DSU(N)


    row_mask = [0]*n
    col_mask = [0]*m

    for r in range(n):
        s = next(it).decode()
        mask = 0
        for c, ch in enumerate(s):
            if ch == '.':
                mask |= 1 << c
                col_mask[c] |= 1 << r
                dsu.union(r, n + c)
        row_mask[r] = mask

    r2r = [None]*n
    c2c = [None]*m

    def ensure_r2r(r):
        if r2r[r] is None:

            res = 0
            rm = row_mask[r]
            while rm:
                lb = rm & -rm
                c = lb.bit_length() - 1
                res |= col_mask[c]
                rm ^= lb
            r2r[r] = res
        return r2r[r]

    def ensure_c2c(c):
        if c2c[c] is None:
            res = 0
            cm = col_mask[c]
            while cm:
                lb = cm & -cm
                r = lb.bit_length() - 1
                res |= row_mask[r]
                cm ^= lb
            c2c[c] = res
        return c2c[c]

    def unreachable(r1, c1, r2, c2):
        a = dsu.find(r1); b = dsu.find(n + c1)
        x = dsu.find(r2); y = dsu.find(n + c2)
        return not (a == x or a == y or b == x or b == y)


    def bidir_bitset_distance(r1, c1, r2, c2):
        RS, CS = (1 << r1), (1 << c1)
        RT, CT = (1 << r2), (1 << c2)

        vRS, vCS = RS, CS
        vRT, vCT = RT, CT
        dS = dT = 0

        while (RS or CS) and (RT or CT):

            if (RS.bit_count() + CS.bit_count()) <= (RT.bit_count() + CT.bit_count()):

                newC = or_rows_to_cols(RS, row_mask) & ~vCS
                newR = or_cols_to_rows(CS, col_mask) & ~vRS

                if (newR & vRT) or (newC & vCT):
                    return dS + 1 + dT

                vRS |= newR; vCS |= newC
                RS, CS = newR, newC
                dS += 1
            else:

                newC = or_rows_to_cols(RT, row_mask) & ~vCT
                newR = or_cols_to_rows(CT, col_mask) & ~vRT

                if (newR & vRS) or (newC & vCS):
                    return dT + 1 + dS

                vRT |= newR; vCT |= newC
                RT, CT = newR, newC
                dT += 1

        return None

    out = []
    for _ in range(q):
        r1 = int(next(it)) - 1
        c1 = int(next(it)) - 1
        r2 = int(next(it)) - 1
        c2 = int(next(it)) - 1

        if r1 == r2 and c1 == c2:
            out.append("0"); continue

        if r1 == r2 or c1 == c2:
            out.append("1"); continue

        if unreachable(r1, c1, r2, c2):
            out.append("-1"); continue

        if ((row_mask[r1] >> c2) & 1) or ((row_mask[r2] >> c1) & 1):
            out.append("2"); continue

        if (row_mask[r1] & row_mask[r2]) or (col_mask[c1] & col_mask[c2]):
            out.append("3"); continue

        if (ensure_r2r(r1) & col_mask[c2]) or (ensure_c2c(c1) & row_mask[r2]):
            out.append("4"); continue
        dist_edges = bidir_bitset_distance(r1, c1, r2, c2)
        out.append(str(dist_edges + 1) if dist_edges is not None else "-1")

    sys.stdout.write("\n".join(out))

if __name__ == "__main__":
    main()

Test details

Test 1 (public)

Group: 1, 2, 3, 4, 5

Verdict: ACCEPTED

input
4 6 5
.*.***
*...**
*****.
*..*.*
...

correct output
1
0
3
3
-1

user output
1
0
3
3
-1

Test 2

Group: 1, 2, 3, 4, 5

Verdict: ACCEPTED

input
10 10 10
..........
.....*....
........*.
*.*....*..
...

correct output
1
2
1
2
2
...

user output
1
2
1
2
2
...

Test 3

Group: 1, 2, 3, 4, 5

Verdict: ACCEPTED

input
10 10 10
*...***.**
*****.*...
**..**.**.
..**.**.*.
...

correct output
1
2
2
1
2
...

user output
1
2
2
1
2
...

Test 4

Group: 1, 2, 3, 4, 5

Verdict: ACCEPTED

input
10 10 10
***.*.****
**********
*.********
.*.***.**.
...

correct output
3
4
2
3
4
...

user output
3
4
2
3
4
...

Test 5

Group: 1, 2, 3, 4, 5

Verdict: ACCEPTED

input
10 10 1
.****.****
**.**..***
**********
*******..*
...

correct output
7

user output
7

Test 6

Group: 2, 5

Verdict: ACCEPTED

input
250 250 250
.*...*.....*******..**...*.......

correct output
2
3
3
2
2
...

user output
2
3
3
2
2
...

Test 7

Group: 2, 5

Verdict: ACCEPTED

input
250 250 250
...*......**.**.*.*..**..*..**...

correct output
2
2
2
2
3
...

user output
2
2
2
2
3
...

Test 8

Group: 2, 5

Verdict: ACCEPTED

input
250 250 250
**..**..****.****.*.***.***..*...

correct output
2
3
3
3
3
...

user output
2
3
3
3
3
...

Test 9

Group: 3, 4, 5

Verdict: ACCEPTED

input
40 40 200000
...*.**.*..*.............*.*.....

correct output
2
2
2
2
2
...

user output
2
2
2
2
2
...

Test 10

Group: 3, 4, 5

Verdict: ACCEPTED

input
40 40 200000
**.**..*.*.*.******....****.*....

correct output
2
1
3
2
2
...

user output
2
1
3
2
2
...

Test 11

Group: 3, 4, 5

Verdict: ACCEPTED

input
40 40 200000
.*.*.**.*****.***.*.****.**.**...

correct output
3
3
3
3
3
...

user output
3
3
3
3
3
...

Test 12

Group: 4, 5

Verdict: ACCEPTED

input
80 80 200000
*....**.***..****...*.....*......

correct output
2
2
2
2
2
...

user output
2
2
2
2
2
...

Test 13

Group: 4, 5

Verdict: ACCEPTED

input
80 80 200000
.***.*..*.***..*****....**...*...

correct output
3
2
2
3
2
...

user output
3
2
2
3
2
...

Test 14

Group: 4, 5

Verdict: ACCEPTED

input
80 80 200000
*******.*****.*..*..****...***...

correct output
2
3
1
2
2
...

user output
2
3
1
2
2
...

Test 15

Group: 5

Verdict: ACCEPTED

input
250 250 200000
*....*..*..*..**..*.........**...

correct output
3
2
2
2
2
...

user output
3
2
2
2
2
...

Test 16

Group: 5

Verdict: ACCEPTED

input
250 250 200000
..*....*..*......*.**.*.*..***...

correct output
2
2
2
2
2
...

user output
2
2
2
2
2
...

Test 17

Group: 5

Verdict: ACCEPTED

input
250 250 200000
*..*.*****.*********.****.****...

correct output
3
3
2
2
2
...

user output
3
3
2
2
2
...

Test 18

Group: 5

Verdict: ACCEPTED

input
250 250 200000
*********.**********.******.**...

correct output
3
3
3
3
3
...

user output
3
3
3
3
3
...

Test 19

Group: 5

Verdict:

input
250 250 200000
.*****************************...

correct output
104
422
145
93
65
...

user output
(empty)

Test 20

Group: 5

Verdict:

input
250 250 200000
..****************************...

correct output
57
155
38
65
98
...

user output
(empty)

Test 21

Group: 5

Verdict:

input
250 250 200000
.*****************************...

correct output
498
498
498
498
498
...

user output
(empty)

Test 22

Group: 1, 2, 3, 4, 5

Verdict: ACCEPTED

input
10 1 10
*
*
.
*
...

correct output
0
1
1
0
0
...

user output
0
1
1
0
0
...

Test 23

Group: 1, 2, 3, 4, 5

Verdict: ACCEPTED

input
1 10 10
........*.
1 7 1 10
1 4 1 7
1 5 1 1
...

correct output
1
1
1
1
1
...

user output
1
1
1
1
1
...

Test 24

Group: 5

Verdict: ACCEPTED

input
250 1 200000
*
.
*
.
...

correct output
1
1
1
1
1
...

user output
1
1
1
1
1
...

Test 25

Group: 5

Verdict: ACCEPTED

input
1 250 200000
*.*.*...*.*.**.***..**.*.*..**...

correct output
1
1
1
1
1
...

user output
1
1
1
1
1
...

Test 26

Group: 5

Verdict: ACCEPTED

input
250 250 200000
.................................

correct output
2
2
2
2
2
...

user output
2
2
2
2
2
...

Test 27

Group: 5

Verdict: ACCEPTED

input
250 250 200000
******************************...

correct output
0
0
0
0
0
...

user output
0
0
0
0
0
...