0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ABC434Dを解いた【2次元imos法】

Last updated at Posted at 2025-12-03

筆者はレート800前後の茶~緑コーダ

ABC434のD問題を解いていく

実装コード

雲の領域を塗りつぶすために、2 次元 imos 法を用いる。

いくつの領域が重なっているかを数える cc と、
重なっている領域の番号の総和を管理する ck を用いる。

  • cc[i][j]が 0 のときは、どの雲にも覆われていないマス
  • cc[i][j]が 1 のときは、ちょうど 1 つの雲だけが覆っているマスで、その雲の番号がck[i][j]になっている

と判断できるので、これらの値を数えて回答すればOK

main.py
from bisect import bisect_left, bisect_right, insort_left, insort_right
from collections import defaultdict, Counter, deque
from functools import reduce, lru_cache
from itertools import product, accumulate, groupby, combinations
import sys
import os
def rI(): return int(sys.stdin.readline().rstrip())
def rLI(): return list(map(int,sys.stdin.readline().rstrip().split()))
def rI1(): return (int(sys.stdin.readline().rstrip())-1)
def rLI1(): return list(map(lambda a:int(a)-1,sys.stdin.readline().rstrip().split()))
def rS(): return sys.stdin.readline().rstrip()
def rLS(): return list(sys.stdin.readline().rstrip().split())
IS_LOCAL = int(os.getenv("ATCODER", "0"))==0
err = (lambda *args, **kwargs: print(*args, **kwargs, file=sys.stderr)) if IS_LOCAL else (lambda *args, **kwargs: None)

M = 2000
K = M+10

def main():
    N = rI()
    cc=[[0]*K for _ in range(K)]
    ck=[[0]*K for _ in range(K)]
    for i in range(1,N+1):
        u, d, l, r = rLI()
        d+=1
        r+=1
        cc[u][l] += 1
        cc[u][r] -= 1
        cc[d][l] -= 1 
        cc[d][r] += 1
        ck[u][l] += i
        ck[u][r] -= i
        ck[d][l] -= i 
        ck[d][r] += i
    for i in range(K-1):
        for j in range(K-1):
            cc[i][j+1] += cc[i][j]
            ck[i][j+1] += ck[i][j]
    for i in range(K-1):
        for j in range(K-1):
            cc[i+1][j] += cc[i][j]
            ck[i+1][j] += ck[i][j]
    
    ans = [0] * -~N
        
    for i in range(1,M+1):
        for j in range(1,M+1):
            if cc[i][j] == 0:
                ans[0] += 1
            if cc[i][j] == 1:
                ans[ck[i][j]] += 1
    for i in range(N):
        print(ans[0]+ans[i+1])
            
if __name__ == '__main__':
    main()

感想

cc,ckの 2 種類の imos 法を回す発想は思いつかなかった。
imos 法のデバッグに、思ったより時間を費やしてしまった。
1 次元 imos 法なら、累積和の派生系みたいな感覚で簡単なのに、2 次元に増えるだけで一気に複雑に感じる。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?