LoginSignup
1
0

More than 3 years have passed since last update.

AtCoder Beginner Contest 150

Last updated at Posted at 2020-01-11

今回まだunratedになった。

C - Count Order

直接にitertools.permutationsを利用する。

from itertools import permutations as perm
import sys
readline = sys.stdin.buffer.readline

n = int(readline())
p = tuple(map(int, readline().split()))
q = tuple(map(int, readline().split()))

p_lst = list(perm(list(range(1, n + 1)), n))  # 排列を生成する。辞書順整理済み
pn = qn = 0
for i, j in enumerate(p_lst, 1):
    if p == j:
        pn = i
    if q == j:
        qn = i
    if pn * qn != 0:
        print(abs(pn - qn))
        quit()

D - Semi Common Multiple

import sys
read = sys.stdin.buffer.read
from fractions import gcd
from functools import reduce

n, m, *alst = map(int, read().split())
mm = 2 * m  # 2Xはaiの奇数倍


def lcm(x, y):
    g = gcd(x, y)
    if x // g % 2 == 0 or y // g % 2 == 0:
    # 両方の余りが同時1でないとlcmがどちらかの偶数倍になる
        print(0)
        quit()
    g = x * y // g
    if g > mm:
        print(0)
        quit()
    return g


g = reduce(lcm, alst)
res = (mm // g)
print(res // 2 + res % 2)

E - Change a Little Bit

C列が整理済みとする。(C1<=C2<=C3...)
規則を見つけてみる。

n=1, 0 C1
1 1
合計 1
n=2, 00 C1 C2
01 0 1
10 1 0
11 2 1
合計 3 2
n=3, 000 C1 C2 C3
001 0 0 1
010 0 1 0
100 1 0 0
011 0 2 1
101 2 0 1
110 2 1 0
111 3 2 1
合計 8 6 4
n=4, 0000 C1 C2 C3 C4
... ... ... ... ...
合計 20 16 12 8

よって規則は、
$\quad 2^{n}* {\sum_1^n} C_i*(n+2-i)*2^{n-2}$

$ = 4^{n-1}* {\sum_1^n} C_i*(n+2-i)$
(n=1時も満足する)

import sys
read = sys.stdin.buffer.read

mod = 10**9 + 7
n, *clst = map(int, read().split())
clst.sort()
res = sum((n + 2 - i) * item for i, item in enumerate(clst, 1))
print((4**(n - 1) * res) % mod)

F - Xor Shift

自分のKMPが全然間に合わなかったからZ-functionを勉強した。
Z-function and its calculation

import sys
read = sys.stdin.buffer.read

n, *lst = map(int, read().split())
al = lst[:n]
bl = lst[n:]


def convert(A):
    return [x ^ y for x, y in zip(A, A[1:])] + [A[-1] ^ A[0]]


a = convert(al)
b = convert(bl)


def Z_algorithm(s):
    n = len(s)
    z = [0] * n
    l, r = 0, 0
    for i in range(1, n):
        if i <= r:
            z[i] = z[i - l] if z[i - l] < r - i else r - i - 1
        while i + z[i] < n and s[z[i]] == s[i + z[i]]:
            z[i] += 1
        if i + z[i] - 1 > r:
            l, r = i, i + z[i] - 1
    return z


Z = Z_algorithm(b + [-1] + a + a)[n + 1:n + n + 1]

K = [i for i, x in enumerate(Z) if x == n]
X = [al[k] ^ bl[0] for k in K]

print('\n'.join('{} {}'.format(k, x) for k, x in zip(K, X)))

コードはともかく、重要なのはZ-functionの理解です。

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