首页 > 其他分享 >Codeforces Round 952 (Div. 4)

Codeforces Round 952 (Div. 4)

时间:2024-06-16 09:30:20浏览次数:28  
标签:10 int 952 Codeforces leq output test input Div

A. Creating Words

time limit per test: 1 second
memory limit per test: 256 megabytes
input: standard input
output: standard output

Matthew is given two strings a a a and b b b, both of length 3 3 3. He thinks it’s particularly funny to create two new words by swapping the first character of a a a with the first character of b b b. He wants you to output a a a and b b b after the swap.

Note that the new words may not necessarily be different.

Input

The first line contains t t t ( 1 ≤ t ≤ 100 1 \leq t \leq 100 1≤t≤100) — the number of test cases.

The first and only line of each test case contains two space-separated strings, a a a and b b b, both of length 3 3 3. The strings only contain lowercase Latin letters.

Output

For each test case, after the swap, output a a a and b b b, separated by a space.

Example

i n p u t \tt input input
6
bit set
cat dog
hot dog
uwu owo
cat cat
zzz zzz
o u t p u t \tt output output
sit bet
dat cog
dot hog
owu uwo
cat cat
zzz zzz

Tutorial

交换首字母输出,可以交换后输出,也可以先输出首字母,再输出另一个字符串的后两个字母

此解法时间复杂度为 O ( 1 ) \mathcal O(1) O(1)

Solution

for _ in range(int(input())):
    a, b = map(str, input().split())
    print(b[0] + a[1:], a[0] + b[1:])

B. Maximum Multiple Sum

time limit per test: 1 second
memory limit per test: 256 megabytes
input: standard input
output: standard output

Given an integer n n n, find an integer x x x such that:

  • 2 ≤ x ≤ n 2 \leq x \leq n 2≤x≤n.
  • The sum of multiples of x x x that are less than or equal to n n n is maximized. Formally, x + 2 x + 3 x + ⋯ + k x x + 2x + 3x + \dots + kx x+2x+3x+⋯+kx where k x ≤ n kx \leq n kx≤n is maximized over all possible values of x x x.

Input

The first line contains t t t ( 1 ≤ t ≤ 100 1 \leq t \leq 100 1≤t≤100) — the number of test cases.

Each test case contains a single integer n n n ( 2 ≤ n ≤ 100 2 \leq n \leq 100 2≤n≤100).

Output

For each test case, output an integer, the optimal value of x x x. It can be shown there is only one unique answer.

Example

i n p u t \tt input input
2
3
15
o u t p u t \tt output output
3
2

Note

For n = 3 n = 3 n=3, the possible values of x x x are 2 2 2 and 3 3 3. The sum of all multiples of 2 2 2 less than or equal to n n n is just 2 2 2, and the sum of all multiples of 3 3 3 less than or equal to n n n is 3 3 3. Therefore, 3 3 3 is the optimal value of x x x.

For n = 15 n = 15 n=15, the optimal value of x x x is 2 2 2. The sum of all multiples of 2 2 2 less than or equal to n n n is 2 + 4 + 6 + 8 + 10 + 12 + 14 = 56 2 + 4 + 6 + 8 + 10 + 12 + 14 = 56 2+4+6+8+10+12+14=56, which can be proven to be the maximal over all other possible values of x x x.

Tutorial

根据题目原理枚举 k k k,暴力的出答案

此解法时间复杂度为 O ( n 2 ) \mathcal O(n ^ 2) O(n2)

Solution

for _ in range(int(input())):
    n = int(input())
    ans, cnt = 0, 0
    for i in range(2, n + 1):
        mid = 0
        j = 1
        while j * i <= n:
            mid += i * j
            j += 1
        if mid > cnt:
            ans = i
            cnt = mid
    print(ans)

C. Good Prefixes

time limit per test: 2 second
memory limit per test: 256 megabytes
input: standard input
output: standard output

Alex thinks some array is good if there exists some element that can be represented as the sum of all other elements (the sum of all other elements is 0 0 0 if there are no other elements). For example, the array [ 1 , 6 , 3 , 2 ] [1,6,3,2] [1,6,3,2] is good since 1 + 3 + 2 = 6 1+3+2=6 1+3+2=6. Furthermore, the array [ 0 ] [0] [0] is also good. However, the arrays [ 1 , 2 , 3 , 4 ] [1,2,3,4] [1,2,3,4] and [ 1 ] [1] [1] are not good.

Alex has an array a 1 , a 2 , … , a n a_1,a_2,\ldots,a_n a1​,a2​,…,an​. Help him count the number of good non-empty prefixes of the array a a a. In other words, count the number of integers i i i ( 1 ≤ i ≤ n 1 \le i \le n 1≤i≤n) such that the length i i i prefix (i.e. a 1 , a 2 , … , a i a_1,a_2,\ldots,a_i a1​,a2​,…,ai​) is good.

Input

The first line of the input contains a single integer t t t ( 1 ≤ t ≤ 1 0 4 1 \leq t \leq 10^4 1≤t≤104) — the number of test cases.

The first line of each test case contains a single integer n n n ( 1 ≤ n ≤ 2 ⋅ 1 0 5 1 \le n \le 2 \cdot 10^5 1≤n≤2⋅105) — the number of elements in the array.

The second line of each test case contains n n n integers a 1 , a 2 , … , a n a_1,a_2,\ldots,a_n a1​,a2​,…,an​ ( 0 ≤ a i ≤ 1 0 9 0 \le a_i \le 10^9 0≤ai​≤109) — the elements of the array.

It is guaranteed that the sum of n n n over all test cases does not exceed 2 ⋅ 1 0 5 2 \cdot 10^5 2⋅105.

Output

For each test case, output a single integer — the number of good non-empty prefixes of the array a a a.

Example

i n p u t \tt input input
7
1
0
1
1
4
1 1 2 0
5
0 1 2 1 4
7
1 1 0 3 5 2 12
7
1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 294967296
10
0 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 589934592
o u t p u t \tt output output
1
0
3
3
4
1
2

Note

In the fourth test case, the array has five prefixes:

  • prefix [ 0 ] [0] [0] is a good array, as mentioned in the statement;
  • prefix [ 0 , 1 ] [0, 1] [0,1] is not a good array, since 0 ≠ 1 0 \ne 1 0=1;
  • prefix [ 0 , 1 , 2 ] [0, 1, 2] [0,1,2] is not a good array, since 0 ≠ 1 + 2 0 \ne 1 + 2 0=1+2, 1 ≠ 0 + 2 1 \ne 0 + 2 1=0+2 and 2 ≠ 0 + 1 2 \ne 0 + 1 2=0+1;
  • prefix [ 0 , 1 , 2 , 1 ] [0, 1, 2, 1] [0,1,2,1] is a good array, since 2 = 0 + 1 + 1 2 = 0 + 1 + 1 2=0+1+1;
  • prefix [ 0 , 1 , 2 , 1 , 4 ] [0, 1, 2, 1, 4] [0,1,2,1,4] is a good array, since 4 = 0 + 1 + 2 + 1 4 = 0 + 1 + 2 + 1 4=0+1+2+1.

As you can see, three of them are good, so the answer is 3 3 3.

Tutorial

由题意得,需要判断在前缀内,最大值等于其他所有元素之和,即判断前缀最大值的两倍是否等于前缀和即可

遍历一遍,动态维护最大值和前缀和即可

此解法时间复杂度为 O ( n ) \mathcal O(n) O(n)

Solution

for _ in range(int(input())):
    n = int(input())
    a = list(map(int, input().split()))
    cnt = 0
    ans, mx = 0, 0
    for ai in a:
        mx = max(mx, ai)
        cnt += ai
        if cnt - mx == mx:
            ans += 1
    print(ans)

D. Manhattan Circle

time limit per test: 2 second
memory limit per test: 256 megabytes
input: standard input
output: standard output

Given a n n n by m m m grid consisting of ‘.’ and ‘#’ characters, there exists a whole manhattan circle on the grid. The top left corner of the grid has coordinates ( 1 , 1 ) (1,1) (1,1), and the bottom right corner has coordinates ( n , m ) (n, m) (n,m).

Point ( a , b a, b a,b) belongs to the manhattan circle centered at ( h , k h, k h,k) if ∣ h − a ∣ + ∣ k − b ∣ < r |h - a| + |k - b| < r ∣h−a∣+∣k−b∣<r, where r r r is a positive constant.

On the grid, the set of points that are part of the manhattan circle is marked as ‘#’. Find the coordinates of the center of the circle.

Input

The first line contains t t t ( 1 ≤ t ≤ 1000 1 \leq t \leq 1000 1≤t≤1000) — the number of test cases.

The first line of each test case contains n n n and m m m ( 1 ≤ n ⋅ m ≤ 2 ⋅ 1 0 5 1 \leq n \cdot m \leq 2 \cdot 10^5 1≤n⋅m≤2⋅105) — the height and width of the grid, respectively.

The next n n n lines contains m m m characters ‘.’ or ‘#’. If the character is ‘#’, then the point is part of the manhattan circle.

It is guaranteed the sum of n ⋅ m n \cdot m n⋅m over all test cases does not exceed 2 ⋅ 1 0 5 2 \cdot 10^5 2⋅105, and there is a whole manhattan circle on the grid.

Output

For each test case, output the two integers, the coordinates of the center of the circle.

Example

i n p u t \tt input input
6
5 5


…#…


5 5
…#…
.###.
#####
.###.
…#…
5 6


.#…
###…
.#…
1 1
#
5 6
…#…
…###.
.#####
…###.
…#…
2 10

…#…
o u t p u t \tt output output
3 3
3 3
4 2
1 1
3 4
2 4

Tutorial

先从上往下找到第一个出现 # 的行,此时可以得到中心点的列坐标,然后在那一列寻找 # 出现的上边界和下边界,中心点即为当前列上边界和下边界的中点

此解法时间复杂度为 O ( n 2 ) \mathcal O(n ^ 2) O(n2)

Solution

for _ in range(int(input())):
    n, m = map(int, input().split())
    g = [input() for __ in range(n)]
    y = -1
    up, down = -1, -1
    for i in range(n):
        for j in range(m):
            if g[i][j] == '#':
                y = j
                up = i
                break
        if y != -1:
            break
    for i in range(up, n):
        if g[i][y] == '#':
            down = i
    print(((up + down) >> 1) + 1, y + 1)

E. Secret Box

time limit per test: 1 second
memory limit per test: 256 megabytes
input: standard input
output: standard output

Ntarsis has a box B B B with side lengths x x x, y y y, and z z z. It lies in the 3D coordinate plane, extending from ( 0 , 0 , 0 ) (0,0,0) (0,0,0) to ( x , y , z ) (x,y,z) (x,y,z).

Ntarsis has a secret box S S S. He wants to choose its dimensions such that all side lengths are positive integers, and the volume of S S S is k k k. He can place S S S somewhere within B B B such that:

  • S S S is parallel to all axes.
  • every corner of S S S lies on an integer coordinate.

S S S is magical, so when placed at an integer location inside B B B, it will not fall to the ground.

Among all possible ways to choose the dimensions of S S S, determine the maximum number of distinct locations he can choose to place his secret box S S S inside B B B. Ntarsis does not rotate S S S once its side lengths are selected.

Input

The first line consists of an integer t t t, the number of test cases ( 1 ≤ t ≤ 2000 1 \leq t \leq 2000 1≤t≤2000). The description of the test cases follows.

The first and only line of each test case contains four integers x , y , z x, y, z x,y,z and k k k ( 1 ≤ x , y , z ≤ 2000 1 \leq x, y, z \leq 2000 1≤x,y,z≤2000, 1 ≤ k ≤ x ⋅ y ⋅ z 1 \leq k \leq x \cdot y \cdot z 1≤k≤x⋅y⋅z).

It is guaranteed the sum of all x x x, sum of all y y y, and sum of all z z z do not exceed 2000 2000 2000 over all test cases.

Note that k k k may not fit in a standard 32-bit integer data type.

Output

For each test case, output the answer as an integer on a new line. If there is no way to select the dimensions of S S S so it fits in B B B, output 0 0 0.

Example

i n p u t \tt input input
7
3 3 3 8
3 3 3 18
5 1 1 1
2 2 2 7
3 4 2 12
4 3 1 6
1800 1800 1800 4913000000
o u t p u t \tt output output
8
2
5
0
4
4
1030301

Note

For the first test case, it is optimal to choose S S S with side lengths 2 2 2, 2 2 2, and 2 2 2, which has a volume of 2 ⋅ 2 ⋅ 2 = 8 2 \cdot 2 \cdot 2 = 8 2⋅2⋅2=8. It can be shown there are 8 8 8 ways to put S S S inside B B B.

The coordinate with the least x x x, y y y, and z z z values for each possible arrangement of S S S are:

  1. ( 0 , 0 , 0 ) (0, 0, 0) (0,0,0)
  2. ( 1 , 0 , 0 ) (1, 0, 0) (1,0,0)
  3. ( 0 , 1 , 0 ) (0, 1, 0) (0,1,0)
  4. ( 0 , 0 , 1 ) (0, 0, 1) (0,0,1)
  5. ( 1 , 0 , 1 ) (1, 0, 1) (1,0,1)
  6. ( 1 , 1 , 0 ) (1, 1, 0) (1,1,0)
  7. ( 0 , 1 , 1 ) (0, 1, 1) (0,1,1)
  8. ( 1 , 1 , 1 ) (1, 1, 1) (1,1,1)

The arrangement of S S S with a coordinate of ( 0 , 0 , 0 ) (0, 0, 0) (0,0,0) is depicted below:

For the second test case, S S S with side lengths 2 2 2, 3 3 3, and 3 3 3 are optimal.

Tutorial

暴力枚举其中两个维度,然后通过除法操作判断第三维是否满足条件,如果满足条件,那么此时 S S S 三边的长度已知,可以根据 B B B​ 三边的长度分别找到对应维度有多少种放法,相乘判断大小即可

对于一个维度的方法,如果 B B B 当前维度长度为 a a a, S S S 当前维度长度为 b b b,则有 a − b + 1 a - b + 1 a−b+1 种放法

此解法时间复杂度为 O ( max ⁡ ( x , y , z ) 2 ) \mathcal O(\max(x, y, z) ^ 2) O(max(x,y,z)2)

Solution

for _ in range(int(input())):
    ans = 0
    x, y, z, k = map(int, input().split())
    for i in range(1, x + 1):
        for j in range(1, y + 1):
            if k % (i * j) == 0 and 1 <= k // (i * j) <= z:
                ans = max(ans, (x - i + 1) * (y - j + 1) * (z - k // (i * j) + 1))
    print(ans)

F. Final Boss

time limit per test: 2 second
memory limit per test: 256 megabytes
input: standard input
output: standard output

You are facing the final boss in your favorite video game. The boss enemy has h h h health. Your character has n n n attacks. The i i i’th attack deals a i a_i ai​ damage to the boss but has a cooldown of c i c_i ci​ turns, meaning the next time you can use this attack is turn x + c i x + c_i x+ci​ if your current turn is x x x. Each turn, you can use all attacks that are not currently on cooldown, all at once. If all attacks are on cooldown, you do nothing for the turn and skip to the next turn.

Initially, all attacks are not on cooldown. How many turns will you take to beat the boss? The boss is beaten when its health is 0 0 0 or less.

Input

The first line contains t t t ( 1 ≤ t ≤ 1 0 4 1 \leq t \leq 10^4 1≤t≤104) – the number of test cases.

The first line of each test case contains two integers h h h and n n n ( 1 ≤ h , n ≤ 2 ⋅ 1 0 5 1 \leq h, n \leq 2 \cdot 10^5 1≤h,n≤2⋅105) – the health of the boss and the number of attacks you have.

The following line of each test case contains n n n integers a 1 , a 2 , . . . , a n a_1, a_2, ..., a_n a1​,a2​,...,an​ ( 1 ≤ a i ≤ 2 ⋅ 1 0 5 1 \leq a_i \leq 2 \cdot 10^5 1≤ai​≤2⋅105) – the damage of your attacks.

The following line of each test case contains n n n integers c 1 , c 2 , . . . , c n c_1, c_2, ..., c_n c1​,c2​,...,cn​ ( 1 ≤ c i ≤ 2 ⋅ 1 0 5 1 \leq c_i \leq 2 \cdot 10^5 1≤ci​≤2⋅105) – the cooldown of your attacks.

It is guaranteed that the sum of h h h and n n n over all test cases does not exceed 2 ⋅ 1 0 5 2 \cdot 10^5 2⋅105.

Output

For each test case, output an integer, the minimum number of turns required to beat the boss.

Example

i n p u t \tt input input
8
3 2
2 1
2 1
5 2
2 1
2 1
50 3
5 6 7
5 6 7
50 3
2 2 2
3 3 3
90000 2
200000 200000
1 1
100000 1
1
200000
6 7
3 2 3 2 3 1 2
6 5 9 5 10 7 7
21 6
1 1 1 1 1 1
5 5 8 10 7 6
o u t p u t \tt output output
1
3
15
25
1
19999800001
1
21

Note

For the first test case, you can use attacks 1 1 1 and 2 2 2 on the first turn, dealing 3 3 3 damage in total, and slaying the boss.

For the second case, you can beat the boss in 3 3 3 turns by using the following attacks:

Turn 1 1 1: Use attacks 1 1 1 and 2 2 2, dealing 3 3 3 damage to the boss. The boss now has 2 2 2 health left.

Turn 2 2 2: Use attack 2 2 2, dealing 1 1 1 damage to the boss. The boss now has 1 1 1 health left.

Turn 3 3 3: Use attack 1 1 1, dealing 2 2 2 damage to the boss. The boss now has − 1 -1 −1 health left. Since its health is less than or equal to 0 0 0, you beat the boss.

For the sixth test case: remember to use 64-bit integers as the answer can get large.

Tutorial

可以在第一轮就把所有的攻击使用掉,然后在今后的每一轮,只要冷却一到就将其使用掉,那么可以用堆动态维护下一个结束冷却的攻击,并将其下一次攻击时间计算出来

此解法时间复杂度为 O ( h log ⁡ h ) \mathcal O(h \log h) O(hlogh)

Solution

import sys
input = lambda: sys.stdin.readline().strip()
from heapq import heappush, heappop

for _ in range(int(input())):
    h, n = map(int, input().split())
    a = list(map(int, input().split()))
    c = list(map(int, input().split()))
    q = []
    for i in range(n):
        h -= a[i]
        heappush(q, (c[i], i))
    ans = 0
    while h > 0:
        round, i = heappop(q)
        h -= a[i]
        heappush(q, (round + c[i], i))
        ans = round
    print(ans + 1)

G. D-Function

time limit per test: 2 second
memory limit per test: 256 megabytes
input: standard input
output: standard output

Let D ( n ) D(n) D(n) represent the sum of digits of n n n. For how many integers n n n where 1 0 l ≤ n < 1 0 r 10^{l} \leq n < 10^{r} 10l≤n<10r satisfy D ( k ⋅ n ) = k ⋅ D ( n ) D(k \cdot n) = k \cdot D(n) D(k⋅n)=k⋅D(n)? Output the answer modulo 1 0 9 + 7 10^9+7 109+7.

Input

The first line contains an integer t t t ( 1 ≤ t ≤ 1 0 4 1 \leq t \leq 10^4 1≤t≤104) – the number of test cases.

Each test case contains three integers l l l, r r r, and k k k ( 0 ≤ l < r ≤ 1 0 9 0 \leq l < r \leq 10^9 0≤l<r≤109, 1 ≤ k ≤ 1 0 9 1 \leq k \leq 10^9 1≤k≤109).

Output

For each test case, output an integer, the answer, modulo 1 0 9 + 7 10^9 + 7 109+7.

Example

i n p u t \tt input input
6
0 1 4
0 2 7
1 2 1
1 2 3
582 74663 3
0 3 1
o u t p u t \tt output output
2
3
90
12
974995667
999

Note

For the first test case, the only values of n n n that satisfy the condition are 1 1 1 and 2 2 2.

For the second test case, the only values of n n n that satisfy the condition are 1 1 1, 10 10 10, and 11 11 11.

For the third test case, all values of n n n between 10 10 10 inclusive and 100 100 100 exclusive satisfy the condition.

Tutorial

根据题意,想要满足 D ( k ⋅ n ) = k ⋅ D ( n ) D(k \cdot n) = k \cdot D(n) D(k⋅n)=k⋅D(n),就是需要 n n n 的每一位在乘以 k k k 上后都不能进位

对于每一个数位上,一共有 9 k + 1 \frac{9}{k} + 1 k9​+1 种可以取的数字,所以此时可以直接前缀和思想,小于 1 0 l 10 ^ l 10l 且满足此情况的有 ( 9 k + 1 ) l (\frac{9}{k} + 1) ^ l (k9​+1)l 个数,小于 1 0 r 10 ^ r 10r 且满足此情况的有 ( 9 k + 1 ) r (\frac{9}{k} + 1) ^ r (k9​+1)r​ 个数

所以答案就是 ( 9 k + 1 ) r − ( 9 k + 1 ) l (\frac{9}{k} + 1) ^ r - (\frac{9}{k} + 1) ^ l (k9​+1)r−(k9​+1)l,最后注意取余即可

此解法时间复杂度为 O ( log ⁡ r ) \mathcal O(\log r) O(logr),即快速幂的时间复杂度

Solution

mod = 10 ** 9 + 7 # 998244353

for _ in range(int(input())):
    l, r, k = map(int, input().split())
    x = 9 // k + 1
    print((pow(x, r, mod) - pow(x, l, mod)) % mod)

H1. Maximize the Largest Component (Easy Version)

time limit per test: 2 second
memory limit per test: 512 megabytes
input: standard input
output: standard output

Easy and hard versions are actually different problems, so read statements of both problems completely and carefully. The only difference between the two versions is the operation.

Alex has a grid with n n n rows and m m m columns consisting of ‘.’ and ‘#’ characters. A set of ‘#’ cells forms a connected component if from any cell in this set, it is possible to reach any other cell in this set by only moving to another cell in the set that shares a common side. The size of a connected component is the number of cells in the set.

In one operation, Alex selects any row r r r ( 1 ≤ r ≤ n 1 \le r \le n 1≤r≤n) or any column c c c ( 1 ≤ c ≤ m 1 \le c \le m 1≤c≤m), then sets every cell in row r r r or column c c c to be ‘#’. Help Alex find the maximum possible size of the largest connected component of ‘#’ cells that he can achieve after performing the operation at most once.

Input

The first line of the input contains a single integer t t t ( 1 ≤ t ≤ 1 0 4 1 \leq t \leq 10^4 1≤t≤104) — the number of test cases.

The first line of each test case contains two integers n n n and m m m ( 1 ≤ n ⋅ m ≤ 1 0 6 1 \le n \cdot m \le 10^6 1≤n⋅m≤106) — the number of rows and columns of the grid.

The next n n n lines each contain m m m characters. Each character is either ‘.’ or ‘#’.

It is guaranteed that the sum of n ⋅ m n \cdot m n⋅m over all test cases does not exceed 1 0 6 10^6 106.

Output

For each test case, output a single integer — the maximum possible size of a connected component of ‘#’ cells that Alex can achieve.

Example

i n p u t \tt input input
6
1 1
.
4 2

#.
#.
.#
3 5
.#.#.
…#…
.#.#.
5 5
#…#
…#
#…#

…##
6 6
.#…#.
#…#…
.#…#
#.#.#.
.#.##.
###…#
6 8
…#…#
.####.#.
###.#…#
.##.#.##
.#.##.##
#…##.#.
o u t p u t \tt output output
1
6
9
11
15
30

Note

In the second test case, it is optimal for Alex to set all cells in column 2 2 2 to be ‘#’. Doing so will lead to the largest connected component of ‘#’ having a size of 6 6 6.

In the third test case, it is optimal for Alex to set all cells in row 2 2 2 to be ‘#’. Doing so will lead to the largest connected component of ‘#’ having a size of 9 9 9.

In the fourth test case, it is optimal for Alex to set all cells in row 4 4 4 to be ‘#’. Doing so will lead to the largest connected component of ‘#’ having a size of 11 11 11.

Tutorial

本题需要用到并查集和差分

在最开始需要遍历一遍图,将所有连通块找出来,对于每个连通块可以将其所在的行方向的区间和列方向的区间用差分标记出来,其改变的值为该连通块的大小,然后对差分数组进行一遍前缀和即可得到当前行或当前列连接了多少 #

另外,对于每一行(列),统计如果填充当前行(列),会多出多少 #,此时就可以对行(列)一次遍历找出最大值

此解法时间复杂度为 O ( n m ) \mathcal O(nm) O(nm)

Solution

#include <bits/stdc++.h>
using namespace std;

#define endl '\n'
#define int long long

struct DSU { // 并查集
    vector<int> pre, siz;
    
    DSU() {}
    DSU(int n) {
        pre.resize(n + 1);
        std::iota(pre.begin(), pre.end(), 0);
        siz.assign(n + 1, 1);
    }
    
    int find(int x) {
        if (pre[x] == x) {
            return x;
        }
        return pre[x] = find(pre[x]);
    }
    
    bool same(int x, int y) {
        return find(x) == find(y);
    }
    
    bool merge(int x, int y) {
        x = find(x);
        y = find(y);
        if (x == y) {
            return false;
        }
        siz[x] += siz[y];
        pre[y] = x;
        return true;
    }
    
    int size(int x) {
        return siz[find(x)];
    }
};

void solve() {
    int n, m, ans = 0;
    cin >> n >> m;
    vector<string> g(n);
    vector<int> cnt_row(n), cnt_col(m), up(n * m, n), down(n * m, -1), left(n * m, m), right(n * m, -1), diff_row(n), diff_col(m);
    for (string &gi : g) {
        cin >> gi;
    }
    
    DSU dsu(n * m);
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (i + 1 < n and g[i][j] == '#' and g[i + 1][j] == '#') {
                dsu.merge(i * m + j, (i + 1) * m + j);
            }
            if (j + 1 < m and g[i][j] == '#' and g[i][j + 1] == '#') {
                dsu.merge(i * m + j, i * m + j + 1);
            }
        }
    }
    
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (g[i][j] == '.') {
                cnt_row[i]++;
                cnt_col[j]++;
            } else {
                int u = dsu.find(i * m + j);
                up[u] = min(up[u], max(0ll, i - 1));
                down[u] = max(down[u], min(n - 1, i + 1));
                left[u] = min(left[u], max(0ll, j - 1));
                right[u] = max(right[u], min(m - 1, j + 1));
            }
        }
    }

    for (int i = 0; i < n * m; ++i) {
        if (dsu.find(i) == i and g[i / m][i % m] == '#') {
            int sz = dsu.size(i);
            diff_row[up[i]] += sz;
            if (down[i] + 1 < n) {
                diff_row[down[i] + 1] -= sz;
            }
            diff_col[left[i]] += sz;
            if (right[i] + 1 < m) {
                diff_col[right[i] + 1] -= sz;
            }
        }
    }
    ans = max(diff_row[0] + cnt_row[0], diff_col[0] + cnt_col[0]);

    for (int i = 1; i < n; ++i) {
        diff_row[i] += diff_row[i - 1];
        ans = max(ans, diff_row[i] + cnt_row[i]);
    }
    for (int j = 1; j < m; ++j) {
        diff_col[j] += diff_col[j - 1];
        ans = max(ans, diff_col[j] + cnt_col[j]);
    }
    cout << ans << endl;
}

signed main() {
    cin.tie(nullptr)->sync_with_stdio(false);
    int Test; cin >> Test; while (Test--)
    solve();
    return 0;
}

H2. Maximize the Largest Component (Hard Version)

time limit per test: 2 second
memory limit per test: 512 megabytes
input: standard input
output: standard output

Easy and hard versions are actually different problems, so read statements of both problems completely and carefully. The only difference between the two versions is the operation.

Alex has a grid with n n n rows and m m m columns consisting of ‘.’ and ‘#’ characters. A set of ‘#’ cells forms a connected component if from any cell in this set, it is possible to reach any other cell in this set by only moving to another cell in the set that shares a common side. The size of a connected component is the number of cells in the set.

In one operation, Alex selects any row r r r ( 1 ≤ r ≤ n 1 \le r \le n 1≤r≤n) and any column c c c ( 1 ≤ c ≤ m 1 \le c \le m 1≤c≤m), then sets every cell in row r r r and column c c c to be ‘#’. Help Alex find the maximum possible size of the largest connected component of ‘#’ cells that he can achieve after performing the operation at most once.

Input

The first line of the input contains a single integer t t t ( 1 ≤ t ≤ 1 0 4 1 \leq t \leq 10^4 1≤t≤104) — the number of test cases.

The first line of each test case contains two integers n n n and m m m ( 1 ≤ n ⋅ m ≤ 1 0 6 1 \le n \cdot m \le 10^6 1≤n⋅m≤106) — the number of rows and columns of the grid.

The next n n n lines each contain m m m characters. Each character is either ‘.’ or ‘#’.

It is guaranteed that the sum of n ⋅ m n \cdot m n⋅m over all test cases does not exceed 1 0 6 10^6 106.

Output

For each test case, output a single integer — the maximum possible size of a connected component of ‘#’ cells that Alex can achieve.

Example

i n p u t \tt input input
6
1 1
.
4 2

#.
#.
.#
3 5
.#.#.
…#…
.#.#.
5 5
#…#
…#
#…#

…##
6 6
.#…#.
#…#…
.#…#
#.#.#.
.#.##.
###…#
6 8
…#…#
.####.#.
###.#…#
.##.#.##
.#.##.##
#…##.#.
o u t p u t \tt output output
1
7
11
16
22
36

Note

In the fourth test case, it is optimal for Alex to set all cells in row 4 4 4 and column 2 2 2 to be ‘#’. Doing so will lead to the largest connected component of ‘#’ having a size of 16 16 16.

In the fifth test case, it is optimal for Alex to set all cells in row 2 2 2 and column 4 4 4 to be ‘#’. Doing so will lead to the largest connected component of ‘#’ having a size of 22 22 22.

Tutorial

本题需要用到并查集和二维差分,整体思维与 H1 相似

在最开始需要遍历一遍图,将所有连通块找出来,对于每个连通块可以将其所在的行方向的区间和列方向的区间用二维差分标记出来,其改变的值为该连通块的大小,然后在行方向和列方向对差分数组进行一遍二维前缀和即可得到当前位置的行和列连接了多少 #

另外,对于每一行(列),统计如果填充当前行(列),会多出多少 #,此时就可以对行(列)一次遍历找出最大值

此解法时间复杂度为 O ( n m ) \mathcal O(nm) O(nm)​

UPD:搞不清二维差分的可以自己画一下图手推一下,例如下图
在这里插入图片描述

Solution

#include <bits/stdc++.h>
using namespace std;

#define endl '\n'
#define int long long

struct DSU { // 并查集
    vector<int> pre, siz;
    
    DSU() {}
    DSU(int n) {
        pre.resize(n + 1);
        std::iota(pre.begin(), pre.end(), 0);
        siz.assign(n + 1, 1);
    }
    
    int find(int x) {
        if (pre[x] == x) {
            return x;
        }
        return pre[x] = find(pre[x]);
    }
    
    bool same(int x, int y) {
        return find(x) == find(y);
    }
    
    bool merge(int x, int y) {
        x = find(x);
        y = find(y);
        if (x == y) {
            return false;
        }
        siz[x] += siz[y];
        pre[y] = x;
        return true;
    }
    
    int size(int x) {
        return siz[find(x)];
    }
};

void solve() {
    int n, m, ans = 0;
    cin >> n >> m;
    vector<string> g(n);
    vector<int> cnt_row(n), cnt_col(m), up(n * m, n), down(n * m, -1), left(n * m, m), right(n * m, -1);
    vector diff(n, vector<int>(m));
    for (string &gi : g) {
        cin >> gi;
    }
    
    DSU dsu(n * m);
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (i + 1 < n and g[i][j] == '#' and g[i + 1][j] == '#') {
                dsu.merge(i * m + j, (i + 1) * m + j);
            }
            if (j + 1 < m and g[i][j] == '#' and g[i][j + 1] == '#') {
                dsu.merge(i * m + j, i * m + j + 1);
            }
        }
    }
    
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (g[i][j] == '.') {
                cnt_row[i]++;
                cnt_col[j]++;
            } else {
                int u = dsu.find(i * m + j);
                up[u] = min(up[u], max(0ll, i - 1));
                down[u] = max(down[u], min(n - 1, i + 1));
                left[u] = min(left[u], max(0ll, j - 1));
                right[u] = max(right[u], min(m - 1, j + 1));
            }
        }
    }

    for (int i = 0; i < n * m; ++i) {
        if (dsu.find(i) == i and g[i / m][i % m] == '#') {
            int sz = dsu.size(i);
            diff[up[i]][left[i]] -= sz;
            diff[up[i]][0] += sz;
            diff[0][left[i]] += sz;
            if (down[i] + 1 < n) {
                diff[down[i] + 1][left[i]] += sz;
                diff[down[i] + 1][0] -= sz;
                if (right[i] + 1 < m) {
                    diff[down[i] + 1][right[i] + 1] -= sz;
                }
            }
            if (right[i] + 1 < m) {
                diff[up[i]][right[i] + 1] += sz;
                diff[0][right[i] + 1] -= sz;
            }
        }
    }

    for (int i = 0; i < n; ++i) {
        for (int j = 1; j < m; ++j) {
            diff[i][j] += diff[i][j - 1];
        }
    }
    for (int i = 1; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            diff[i][j] += diff[i - 1][j];
        }
    }

    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            ans = max(ans, diff[i][j] + cnt_row[i] + cnt_col[j] - (g[i][j] == '.'));
        }
    }
    cout << ans << endl;
}

signed main() {
    cin.tie(nullptr)->sync_with_stdio(false);
    int Test; cin >> Test; while (Test--)
    solve();
    return 0;
}

标签:10,int,952,Codeforces,leq,output,test,input,Div
From: https://blog.csdn.net/m0_69367351/article/details/139616005

相关文章

  • Codeforces Round 947 (Div. 1 + Div. 2)
    发现今天做不了一点题,遂来补以前的比赛。B.378QAQandMocha'sArray秒了。排序,取最小的数记为\(x\),再取最小的无法被\(x\)整除的数记为\(y\),如果仍然存在无法被\(y\)整除的数,则无解。C.ChamoandMocha'sArray容易想到一个结论:如果一个数比它左边或右边的数小,那么......
  • Codeforces Round 836题解(A、B、C)
    A.SSeeeeiinnggDDoouubbllee直接将原字符串翻转一下拼到原字符串的后面就构成了回文串。strings;voidsolve(){cin>>s;cout<<s;reverse(s.begin(),s.end());cout<<s<<'\n';}B.XOR=Average分\(n\)的奇偶性考虑,若\(n\)为奇数,我们可以......
  • div+css布局实现个人网页设计(HTML期末作业)
    ......
  • Codeforces Round 952 (Div. 4) 题解分享
    A.CreatingWords思路模拟,交换输出即可codeinlinevoidsolve(){stringa,b;cin>>a>>b;swap(a[0],b[0]);cout<<a<<''<<b<<endl; return;}B.MaximumMultipleSum思路暴力枚举数学不会()codein......
  • Codeforces Round 952 (Div. 4)
    A读入两个字符串,交换第一位即可。B题意给定整数\(n\),求一个整数\(x\),满足:\(2\leqx\leqn\)。\(\displaystyle\sum\limits_{i=1}^ki\cdotx\)最大,其中\(k\)为满足\(kx\leqn\)最大的正整数。思路赛时思路可以直接枚举\(x\)的所有情况,暴力计算答案。......
  • Codeforces Round 952 (Div. 4)
    link赛时过了ABCD,rank15270,我嘞个豆啊,虽然菜成shi了,但是打得很开心,凌晨一点多还兴奋得不得了。就是网络好差,比赛开始好几分钟了还被关在外边。A-CreatingWordsB-MaximumMultipleSum签到题,略C-GoodPrefixes想到用前缀和,一开始写成每次往后一位后缀,只对最后一......
  • 如何对嵌套 div 表格进行排序?
    我正在寻找一种解决方案,以便能够根据一个"列"中的值对div表格进行排序。在下面的示例中,排序列的div类为"text-fl"。交互式排序,在这种排序中,数据最初是按照代码中的方式加载的,但如果用户选择按值排序,他们可以点击列标题。由于我的数据不在列表中,因此我认为我无......
  • Codeforces Round 952 (Div. 4)
    A.CreatingWordsvoidsolve(){ stringa,b; cin>>a>>b; swap(a[0],b[0]); cout<<a<<''<<b<<'\n';}B.MaximumMultipleSum总结:作为一个等差数列,快速的找到最高次系数,以及快速求和..C=n/x,sum=(c*x+......
  • 【结构识别】Reconstructing propagation networks with natural diversity and ident
    摘要从数据中重构复杂网络结构和动力学的能力是理解和控制复杂系统集体动力学的基础。尽管最近在这方面取得了进展,但利用随机动态过程的有限时间序列重建网络仍然是一个尚未解决的问题。我们提出了一个基于压缩感知的框架去重构发生随机扩散动力学的复杂网络。我们将该方法应用于......
  • Codeforces Problem 1980B Choosing cubes(基本排序)
    timelimitpertest1secondmemorylimitpertest256megabytesinputstandardinputoutputstandardoutputDmitryhas n......