LoginSignup
1
0

More than 1 year has passed since last update.

yukicoder contest 306 参戦記

Last updated at Posted at 2021-07-24

yukicoder contest 306 参戦記

A 1622 三角形の面積

答えは当然、円に内接する正三角形の面積. ググれば公式がでてくるかもしれないが、2次元なので答えは半径の二乗に比例するので、サンプルを見れば定数が分かる.

t = int(input())
for _ in range(t):
    r = int(input())
    print(1.299038105676657 * r * r)

B 1623 三角形の制作

n は大きくて2重ループは無理だが、ri,gi,bi の値域は2重ループできる程度には小さいのがポイント. OK な条件は ri≧gj かつ ri≧bk かつ ri<gj+bk. rの小さい順に処理しながら順次有効なg, bを投入していけば良い. 条件に合う個数を単純に集計すると遅くて仕方がないので、BIT で高速化した.

class BinaryIndexedTree:
    def __init__(self, size):
        self._data = [0] * size

    def add(self, i, x):
        data = self._data
        i += 1
        n = len(data)
        while i <= n:
            data[i - 1] += x
            i += i & -i

    def _sum(self, stop):
        data = self._data
        result = 0
        i = stop
        while i > 0:
            result += data[i - 1]
            i -= i & -i
        return result

    def range_sum(self, start, stop):
        return self._sum(stop) - self._sum(start)


n = int(input())
r = list(map(int, input().split()))
g = list(map(int, input().split()))
b = list(map(int, input().split()))

rr = [0] * 3001
for i in r:
    rr[i] += 1

gg = [0] * 3001
for i in g:
    gg[i] += 1

bb = [0] * 3001
for i in b:
    bb[i] += 1

gb = [[] for _ in range(3001)]
for i in range(1, 3001):
    x = gg[i]
    if x == 0:
        continue
    for j in range(1, 3001):
        y = bb[j]
        if y == 0:
            continue
        gb[max(i, j)].append((i << 12) + j)

bit = BinaryIndexedTree(6001)
result = 0
for i in range(1, 3001):
    for v in gb[i]:
        x = v >> 12
        y = v & 4095
        bit.add(x + y, gg[x] * bb[y])
    result += rr[i] * bit.range_sum(i + 1, 6001)
print(result)

gj と bk から ri の値域を考えるほうが簡単だった. 累積和しておけば個数は O(1) で求まるし.

from itertools import accumulate

n = int(input())
r = list(map(int, input().split()))
g = list(map(int, input().split()))
b = list(map(int, input().split()))

rr = [0] * 3001
for i in r:
    rr[i] += 1

gg = [0] * 3001
for i in g:
    gg[i] += 1

bb = [0] * 3001
for i in b:
    bb[i] += 1

a = list(accumulate(rr))

result = 0
for i in range(1, 3001):
    x = gg[i]
    if x == 0:
        continue
    for j in range(1, 3001):
        y = bb[j]
        if y == 0:
            continue
        result += (a[min(i + j - 1, 3000)] - a[max(i, j) - 1]) * (x * y)
print(result)
1
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
1
0