AtCoder 最速で緑になる 基礎・典型50問詳細解説　コピペ用コード

本記事は拙著『AtCoder 最速で緑になる 基礎・典型50問詳細解説』のコピペ用コード集ですです。
値段：**100円**(Kindle Unlimited対象)
**【kindle】**
https://www.amazon.co.jp/dp/B0BBB7RKTP

**【booth(pdf)】**
https://booth.pm/ja/items/4102300

冒頭5問をサンプルとして無料公開しています。
https://qiita.com/sano192/items/6361ed72106cb6dd5843

# 1 入力と出力 ABC205 A Dif:6

https://atcoder.jp/contests/abc205/tasks/abc205_a

```python:提出
# 入力の受け取り
A,B=map(int, input().split())

# A×(1/100)×Bを出力
print(A*(1/100)*B)
```

# 2 条件分岐1 ABC219 A Dif:6

https://atcoder.jp/contests/abc219/tasks/abc219_a

```python:提出
# 入力の受け取り
X=int(input())

# 初級の場合
if 0<=X<40:
    # 40-Xを出力
    print(40-X)
# 中級の場合
elif 40<=X<70:
    # 70-Xを出力
    print(70-X)
# 上級の場合
elif 70<=X<90:
    # 90-Xを出力
    print(90-X)
# エキスパートの場合
else:
    # "expert"を出力
    print("expert")
```

# 3 関数 ABC234 A Dif:7

https://atcoder.jp/contests/abc234/tasks/abc234_a

```python:提出
# 入力の受け取り
t=int(input())

# 関数の定義
# 引数；x　返り値：x^2+2x+3
def f(x):
    return x**2+2*x+3

# 答えの計算
ans=f(f(f(t)+t)+f(f(t)))

# 答えの出力
print(ans)
```

# 4 for文 ABC204 B Dif:9

https://atcoder.jp/contests/abc204/tasks/abc204_b

```python:提出
# 入力の受け取り
N=int(input())
A=list(map(int, input().split()))

# 答え
ans=0

# i=0~N-1まで
for i in range(N):
    # A[i]が10より大きければ
    if 10<A[i]:
        # A[i]-10をansにプラスする
        ans+=A[i]-10

# 答えの出力
print(ans)
```

```python:別解
# 入力の受け取り
N=int(input())
A=list(map(int, input().split()))

# 答えの格納用変数
ans=0

# xへAの値を順に入れる
for x in A:
    # 0と(x-10)の大きい方を足す
    ans+=max(0,x-10)

# 答えの出力
print(ans)
```

# 5 文字列操作 ABC232 A Dif:9

https://atcoder.jp/contests/abc232/tasks/abc232_a

```python:提出
# 入力の受け取り
S=input()

# Sの0文字目と2文字目を整数へ変換
S0=int(S[0])
S2=int(S[2])

# 掛け算して出力
print(S0*S2)
```

# 6 文字コード変換 ABC218 B Dif:14

https://atcoder.jp/contests/abc218/tasks/abc218_b

```python:提出
# 入力の受け取り
P=list(map(int, input().split()))

# 答えを格納する変数
ans=""

# i=0~25
for i in range(26):
    # 文字コード「P[i]+96」の文字をansの末尾へ追加
    ans+=chr(P[i]+96)

# 答えを出力
print(ans)
```

```python:別解
# 入力の受け取り
P=list(map(int, input().split()))

def convert(x):
    if x==1:return "a"
    if x==2:return "b"
    if x==3:return "c"
    if x==4:return "d"
    if x==5:return "e"
    if x==6:return "f"
    if x==7:return "g"
    if x==8:return "h"
    if x==9:return "i"
    if x==10:return "j"
    if x==11:return "k"
    if x==12:return "l"
    if x==13:return "m"
    if x==14:return "n"
    if x==15:return "o"
    if x==16:return "p"
    if x==17:return "q"
    if x==18:return "r"
    if x==19:return "s"
    if x==20:return "t"
    if x==21:return "u"
    if x==22:return "v"
    if x==23:return "w"
    if x==24:return "x"
    if x==25:return "y"
    if x==26:return "z"

ans=""

# i=0~25
for i in range(26):
    # P[i]を変換してansの末尾へ追加
    ans+=convert(P[i])

# 答えを出力
print(ans)
```

# 7 リスト操作 ABC241 A Dif:15

https://atcoder.jp/contests/abc241/tasks/abc241_a

```python:提出
# 入力の受け取り
a=list(map(int,input().split()))

# 最初に画面に表示されているのは「0」
k=0

# ボタンを押す
k=a[k]

# ボタンを押す
k=a[k]

# ボタンを押す
k=a[k]

# 答えを出力
print(k)
```

# 8 set ABC240 B Dif:19

https://atcoder.jp/contests/abc240/tasks/abc240_b

```python:提出
# 入力の受け取り
N=int(input())
a=list(map(int,input().split()))

# リスト→セットへ変換
aSet=set(a)

# 長さを出力
print(len(aSet))
```

# 9 図形 ABC246 A Dif:28

https://atcoder.jp/contests/abc246/tasks/abc246_a

```python:提出
# 入力の受け取り
x1,y1=map(int,input().split())
x2,y2=map(int,input().split())
x3,y3=map(int,input().split())

# x1=x2の場合
if x1==x2:
    x4=x3
# x2=x3の場合
elif x2==x3:
    x4=x1
# x3=x1の場合
elif x3==x1:
    x4=x2

# y1=y2の場合
if y1==y2:
    y4=y3
# y2=y3の場合
elif y2==y3:
    y4=y1
# y3=y1の場合
elif y3==y1:
    y4=y2

# 答えの出力
print(x4,y4)
```

# 10 二次元配列、ソート1 ABC201 B Dif:32

https://atcoder.jp/contests/abc201/tasks/abc201_b

```python:提出
# 入力の受け取り
N=int(input())

# 山の高さ、名前を格納するリスト
Mountains=[]

# N回
for i in range(N):
    # 入力の受け取り
    S,T=map(str, input().split())
    # Tを整数へ変換
    T=int(T)
    # T,Sの順に格納
    Mountains.append([T,S])

# 大きい順に並び替え
Mountains.sort(reverse=True)

# 1番目のリストの、1番目の要素を出力
print(Mountains[1][1])
```

# 11 二重ループ ABC234 B Dif:46

https://atcoder.jp/contests/abc234/tasks/abc234_b

```python:提出
# 入力の受け取り
N=int(input())

# 座標の格納用
x=[]
y=[]

# i=0~(N-1)
for i in range(N):
    # 入力の受け取り
    xi,yi=map(int,input().split())
    # 座標の格納
    x.append(xi)
    y.append(yi)

# mathのインポート
import math

# 答え
ans=0

# i=0~(N-1)
for i in range(N):
    # j=(i+1)~(N-1)
    for j in range(i+1,N):
        # 距離の計算
        length=math.sqrt((x[i]-x[j])**2+(y[i]-y[j])**2)
        # そこまでの値より大きければ更新
        ans=max(ans,length)

# 答えの出力
print(ans)
```

# 12 条件分岐2 ABC205 C Dif:63

https://atcoder.jp/contests/abc205/tasks/abc205_c

```python:提出
# 入力の受け取り
A,B,C=map(int, input().split())

# C：偶数
if C%2==0:
    # A：0以上(+)
    if 0<=A:
        # B：0以上(+)
        if 0<=B:
            # |A|<|B|
            if abs(A)<abs(B):
                # 「<」を出力
                print("<")
            # |A|=|B|
            if abs(A)==abs(B):
                # 「=」を出力
                print("=")
            # |A|>|B|
            if abs(A)>abs(B):
                # 「>」を出力
                print(">")
        # B：0未満(-)
        if B<0:
            # |A|<|B|
            if abs(A)<abs(B):
                # 「<」を出力
                print("<")
            # |A|=|B|
            if abs(A)==abs(B):
                # 「=」を出力
                print("=")
            # |A|>|B|
            if abs(A)>abs(B):
                # 「>」を出力
                print(">")

    # A：0未満(-)
    if A<0:
        # B：0以上(+)
        if 0<=B:
            # |A|<|B|
            if abs(A)<abs(B):
                # 「<」を出力
                print("<")
            # |A|=|B|
            if abs(A)==abs(B):
                # 「=」を出力
                print("=")
            # |A|>|B|
            if abs(A)>abs(B):
                # 「>」を出力
                print(">")
        # B：0未満(-)
        if B<0:
            # |A|<|B|
            if abs(A)<abs(B):
                # 「<」を出力
                print("<")
            # |A|=|B|
            if abs(A)==abs(B):
                # 「=」を出力
                print("=")
            # |A|>|B|
            if abs(A)>abs(B):
                # 「>」を出力
                print(">")

# C：奇数
if C%2==1:
    # A：0以上(+)
    if 0<=A:
        # B：0以上(+)
        if 0<=B:
            # |A|<|B|
            if abs(A)<abs(B):
                # 「<」を出力
                print("<")
            # |A|=|B|
            if abs(A)==abs(B):
                # 「=」を出力
                print("=")
            # |A|>|B|
            if abs(A)>abs(B):
                # 「>」を出力
                print(">")
        # B：0未満(-)
        if B<0:
            # |A|<|B|
            if abs(A)<abs(B):
                # 「>」を出力
                print(">")
            # |A|=|B|
            if abs(A)==abs(B):
                # 「>」を出力
                print(">")
            # |A|>|B|
            if abs(A)>abs(B):
                # 「>」を出力
                print(">")

    # A：0未満(-)
    if A<0:
        # B：0以上(+)
        if 0<=B:
            # |A|<|B|
            if abs(A)<abs(B):
                # 「<」を出力
                print("<")
            # |A|=|B|
            if abs(A)==abs(B):
                # 「<」を出力
                print("<")
            # |A|>|B|
            if abs(A)>abs(B):
                # 「<」を出力
                print("<")
        # B：0未満(-)
        if B<0:
            # |A|<|B|
            if abs(A)<abs(B):
                # 「>」を出力
                print(">")
            # |A|=|B|
            if abs(A)==abs(B):
                # 「=」を出力
                print("=")
            # |A|>|B|
            if abs(A)>abs(B):
                # 「<」を出力
                print("<")
```

```python:別解
A,B,C=map(int, input().split())

if C%2==0:
    if abs(A)<abs(B):print("<")
    elif abs(A)==abs(B):print("=")
    else:print(">")
else:
    if 0<=A:
        if 0<=B:
            if abs(A)<abs(B):print("<")
            elif abs(A)==abs(B):print("=")
            else:print(">")
        else:print(">")
    else:
        if 0<=B:print("<")
        else:
            if abs(A)<abs(B):print(">")
            elif abs(A)==abs(B):print("=")
            else:print("<")
```

# 13 周期性 ABC220 C Dif:119

https://atcoder.jp/contests/abc220/tasks/abc220_c

```python:提出
# 入力の受け取り
N=int(input())
A=list(map(int, input().split()))
X=int(input())

# Aの合計
Asum=sum(A)

# 必要なAの数：X//(Aの合計)
quo=X//Asum

# 項数(k)：(Aの個数)×(Aの要素数)
k=N*quo

# 合計(Bsum)：(Aの個数)×(Aの合計)
Bsum=Asum*quo

# Xを超えるまでAの要素を順に足していく
# i=0~(N-1)まで
for i in range(N):
    # 合計に+A[i]
    Bsum+=A[i]
    # 項数に+1
    k+=1
    # X<合計になったら
    if X<Bsum:
        # 答えを出力
        print(k)
        # 終了
        exit()
```

# 14 逆順操作 ABC216 C Dif:145

https://atcoder.jp/contests/abc216/tasks/abc216_c

```python:提出
# 入力の受け取り
N=int(input())

# 答え(最初は空)
ans=""

# Nが0より大きい間
while 0<N:
    # Nが偶数なら
    if N%2==0:
        # ansの左端にBを追加
        ans="B"+ans
        # 2で割る
        N//=2
    # それ以外(Nが奇数なら)
    else:
        # ansの左端にAを追加
        ans="A"+ans
        # 1を引く
        N-=1

# 答えを出力
print(ans)
```

# 15 貪欲法 ABC229 C Dif:165

https://atcoder.jp/contests/abc229/tasks/abc229_c

```python:提出
# 入力の受け取り
N,W=map(int,input().split())

# チーズの情報
Cheese=[]

# N回
for i in range(N):
    # 入力の受け取り
    A,B=map(int,input().split())
    # 情報の格納
    Cheese.append([A,B])

# 美味しさの大きい順にソート
Cheese.sort(reverse=True)

# 答え
ans=0

# i=0～(N-1)まで
for i in range(N):
    # i種類目のチーズの美味しさ
    Delicious=Cheese[i][0]
    # i種類目のチーズの重さ
    Weight=Cheese[i][1]

    # 重さ≤Wなら
    if Weight<=W:
        # 全部載せる
        ans+=Delicious*Weight
        # 載せられる残りの重さ
        W-=Weight
    # そうでないなら(W<重さなら)
    else:
        # W[g]分載せる
        ans+=Delicious*W
        # これ以上載せられないからforを抜ける
        break

# 答えの出力
print(ans)
```

# 16 インタラクティブ ABC244 C Dif:165

https://atcoder.jp/contests/abc244/tasks/abc244_c

```python:提出
# 入力の受け取り
N=int(input())

# すでに使った数の記録
Used=[False]*(2*N+2)

# 最初は「1」を出力
print(1)

# 「1」は使用済み
Used[1]=True

# N回
for i in range(N+1):
    # 青木くんの入力を受け取り
    x=int(input())
    # 「x」は使った
    Used[x]=True

    # x=「0」の場合
    if x==0:
        # 終了
        exit()

    # k=1~(2k+1)
    for k in range(1,2*N+2):
        # まだ使っていないなら
        if Used[k]==False:
            # 「k」を出力
            print(k)
            # 「k」は使った
            Used[k]=True
            # forループを抜ける
            break
```

# 17 連想配列1 ABC206 C Dif:171

https://atcoder.jp/contests/abc206/tasks/abc206_c

```python:提出
# 入力の受け取り
N=int(input())
A=list(map(int, input().split()))

# defaultdictのインポート
from collections import defaultdict

# 要素の出現回数を数える連想配列countを用意
count=defaultdict(int)

# Aのそれぞれの要素(a)について
for i in range(N):
    # 出現回数を+1
    count[A[i]]+=1

# 全組み合わせ=NC2=N*(N-1)//2
ans=N*(N-1)//2

# countの値(x)それぞれについて
for x in count.values():
    # Ai=Ajとなる組の数x*(x-1)//2を引く
    ans-=x*(x-1)//2

# 答えの出力
print(ans)
```

# 18 itertools ABC215 C Dif:178

https://atcoder.jp/contests/abc215/tasks/abc215_c

```python:提出
# 入力の受け取り(Kも文字列として)
S,K=map(str,input().split())

# Kを整数に変換
K=int(K)

# 作れる文字を格納するセット(リストだと重複するものも入ってしまうためセットを使う)
Sset=set()

# itertoolsをインポート
import itertools
# p=(0,1,2),(0,2,1),(1,0,2),(1,2,0),...
for p in itertools.permutations(range(len(S))):
    # 作った文字列を記録する変数
    Stmp=""
    # pを使って文字を作成
    # 例：p=(2,0,1)ならStmp=Sの2文字目+Sの0文字目+Sの1文字目
    for i in p:
        Stmp+=S[i]
    # できた文字をSsetに格納(setへの追加はappendではなくaddであることに注意)
    Sset.add(Stmp)

# ソートするためにリストへ変換
Slist=list(Sset)

# 辞書順にソート
Slist.sort()

# K-1番目の要素を出力
print(Slist[K-1])
```

# 19 二分探索1 ABC231 C Dif:194

https://atcoder.jp/contests/abc231/tasks/abc231_c

```python:提出
# 入力の受け取り
N,Q=map(int,input().split())
A=list(map(int,input().split()))

# Aをソート
A.sort()

# 二分探索
# 引数：x 返り値：「身長がx以上の中で最も小さい人は何番目か」
def Nibutan(x):
    # 左端
    l=0
    # 右端
    r=N-1

    # 1<右端-左端の間
    while 1<r-l:
        # 中央
        c=(l+r)//2

        # A[c]<xならば(条件を満たさない場合)
        if A[c]<x:
            # 左端を中央へ更新
            l=c
        # そうでなければ(x≤A[c] 条件を満たす場合)
        else:
            # 右端を中央へ更新
            r=c
       
    # 右端を返す
    return r

# Q回
for i in range(Q):
    # 入力の受け取り
    x=int(input())

    # xがAの中で最小の要素以下である場合
    if x<=A[0]:
        # N人
        print(N)
    # xがAの中で最大の要素より大きい場合
    elif A[N-1]<x:
        print(0)
    # それ以外
    else:
        # 答えの出力
        print(N-Nibutan(x))
```

```python:別解
# 入力の受け取り
N,Q=map(int,input().split())
A=list(map(int,input().split()))

# Aをソート
A.sort()

# クエリの記録
query=[]

# Q回
for i in range(Q):
    # 入力の受け取り
    x=int(input())
    # [x,i番目のクエリ]と記録
    query.append([x,i])

# クエリをxの小さい順にソート
query.sort()
# 答えの格納用リスト
Ans=[0]*Q

# インデックス：初期値は0
k=0
# 各クエリについて
for x,i in query:
 
    # A[k]<xである限り
    while k<N and A[k]<x:
        # kを先に進める
        k+=1

    # A[k]はx以上
    # i番目のクエリの答えを記録
    Ans[i]=N-k

# 答えの出力
for a in Ans:print(a)
```

# 20 ソート2 ABC209 C Dif:285

https://atcoder.jp/contests/abc209/tasks/abc209_c

```python:提出
# 入力の受け取り
N=int(input())
C=list(map(int, input().split()))

# mod=10^9+7と定義
mod=10**9+7

# Cをソート
C.sort()

# 答えを格納する変数
ans=1

# i=0~(N-1)まで
for i in range(N):
    # もしC[i]-i=0ならば
    if C[i]-i==0:
        # 0を出力
        print(0)
        # 終了
        exit()

    # ansにC[i]-iをかける
    ans*=C[i]-i
    # 余りを取る
    ans%=mod

# 答えを出力
print(ans)
```

# 21 シミュレーション1 ABC214 C Dif:319

https://atcoder.jp/contests/abc214/tasks/abc214_c

```python:提出
# 入力の受け取り
N=int(input())
S=list(map(int, input().split()))
T=list(map(int, input().split()))

# i番目のすぬけ君が初めて宝石をもらう時間
# 初期値は大きい数
time=[10**15]*N

# 1週目
for i in range(N):
    # 次のすぬけ君の番号。i=N-1のとき、次のすぬけ君の番号=Nではなく=0とするためNで割った余りを取る
    next=(i+1)%N
    # 高橋君からもらうのが早いか、隣のすぬけ君からもらうのが早いか
    time[next]=min(T[next],time[i]+S[i])

# 2周目
for i in range(N):
    next=(i+1)%N
    # 1周目で計算した時間が早いか、隣のすぬけ君からもらうのが早いか
    time[next]=min(time[next],time[i]+S[i])

# 答えの出力
for i in range(N):
  print(time[i])
```

# 22 bit全探索 ABC221 C Dif:379

https://atcoder.jp/contests/abc221/tasks/abc221_c

```python:提出
# 入力の受け取り(文字列)
N=input()

# 答え 初期値は0
ans=0

# bitnum=(000000),(000001),(000010),(000011),...,(111111)まで
for bitnum in range(1<<len(N)):
    # グループA,Bを用意
    A=[]
    B=[]

    # shift=0~(Nの桁数-1)まで
    for shift in range(len(N)):
    # bitnumのshift桁目が「0」か「1」か確認
    # 右にshift分シフト演算して「1」とアンド演算
        # 0ならば
        if bitnum>>shift & 1==0:
            # グループAへ追加
            A.append(N[shift])
        # 1ならば
        else:
            # グループBへ追加
            B.append(N[shift])

    # グループAまたはグループBが空なら
    if A==[] or B==[]:
        # 次のbitnum
        continue

    # 大きい順に並び替え
    A.sort(reverse=True)
    B.sort(reverse=True)

    # A,Bを結合
    A_join="".join(A)
    B_join="".join(B)
 
    # 整数にして掛け算
    tmp_ans=int(A_join)*int(B_join)
 
    # ansよりtmp_ansが大きかったらansを更新
    ans=max(ans,tmp_ans)

# 答えの出力
print(ans)
```

# 23 区間の処理 ABC207 C Dif:397

https://atcoder.jp/contests/abc207/tasks/abc207_c

```python:提出
# 入力の受け取り
N=int(input())

# 区間の格納リスト
section=[]

# N回
for i in range(N):
    # 入力の受け取り
    t,l,r=map(int, input().split())
    # t=1の場合
    if t==1:
        # 区間[l,r]を追加
        section.append([l,r])
    # t=2の場合
    elif t==2:
        # 区間[l,r-0.1]を追加
        section.append([l,r-0.1])
    # t=3の場合
    elif t==3:
        # 区間[l+0.1,r]を追加
        section.append([l+0.1,r])
    # t=4の場合
    elif t==4:
        # 区間[l+0.1,r-0.1]を追加
        section.append([l+0.1,r-0.1])

# 答えの格納用変数
ans=0

# i=0~(N-1)まで
for i in range(N):
    # j=(i+1)~(N-1)まで
    for j in range(i+1,N):
        # 区間iの左端
        il=section[i][0]
        # 区間iの右端
        ir=section[i][1]
        # 区間jの左端
        jl=section[j][0]
        # 区間jの右端
        jr=section[j][1]

        # (区間iの左端)≤(区間jの左端)≤(区間iの右端)
        if il<=jl<=ir:
            # 答えにカウント
            ans+=1
        # (区間iの左端)≤(区間jの右端)≤(区間iの右端)
        elif il<=jr<=ir:
            # 答えにカウント
            ans+=1        
        # (区間jの左端)≤(区間iの左端)≤(区間jの右端)
        elif jl<=il<=jr:
            # 答えにカウント
            ans+=1        
        # (区間jの左端)≤(区間iの右端)≤(区間jの右端)
        elif jl<=ir<=jr:
            # 答えにカウント
            ans+=1

# 答えの出力
print(ans)
```

```python:別解
# 入力の受け取り
N=int(input())

# 区間の格納リスト
section=[]

# N回
for i in range(N):
    # 入力の受け取り
    t,l,r=map(int, input().split())
    # t=1の場合
    if t==1:section.append([l,r])
    # t=2の場合
    elif t==2:section.append([l,r-0.1])
    # t=3の場合
    elif t==3:section.append([l+0.1,r])
    # t=4の場合
    else:section.append([l+0.1,r-0.1])

# 答えの格納用変数
ans=0

# i=0~(N-1)まで
for i in range(N):
    # j=(i+1)~(N-1)まで
    for j in range(i+1,N):
        # 区間i,jの右端,左端
        il,ir=section[i]
        jl,jr=section[j]
      
        # max(区間iの左端,区間jの左端)≤min(区間iの右端,区間jの右端)ならば
        # 答えにカウント
        if max(il,jl)<=min(ir,jr):ans+=1

# 答えの出力
print(ans)
```

# 24 座標圧縮 ABC213 C Dif:481

https://atcoder.jp/contests/abc213/tasks/abc213_c

```python:提出
# 入力の受け取り
H,W,N=map(int, input().split())

# カードの[行番号,列番号]を受け取るリスト
cards=[]
# 行番号だけ受け取るリスト
Gyou=[]
# 列番号だけ受け取るリスト
Retu=[]

# N回
for i in range(N):
    # 入力の受け取り
    A,B=map(int, input().split())
    # カードの[行番号,列番号]を受け取り
    cards.append([A,B])
    # 行番号を受け取り
    Gyou.append(A)
    # 列番号を受け取り
    Retu.append(B)

# 重複の削除(setにする)
Gyou=set(Gyou)
# リストに直す(setはソートできない)
Gyou=list(Gyou)
# ソートする
Gyou.sort()

# 変換先を記録する連想配列
GyouConvert=dict()

# 重複削除後の行の個数分
for i in range(len(Gyou)):
    # もとの行番号→インデックス番号+1と変換できるように記録(小さい方から何番目にあるか？)
    GyouConvert[Gyou[i]]=i+1

#列も同じことをする
Retu=set(Retu)
Retu=list(Retu)
Retu.sort()

RetuConvert=dict()

for i in range(len(Retu)):
    RetuConvert[Retu[i]]=i+1

# それぞれのカードについて行、列番号を変換して出力
for Gyou,Retu in cards:
    # 行番号の変換
    AnsGyou=GyouConvert[Gyou]
    # 列番号の変換
    AnsRetu=RetuConvert[Retu]
    # 答えを出力する
    print(AnsGyou,AnsRetu)
```

# 25 heap ABC234 D Dif:503

https://atcoder.jp/contests/abc234/tasks/abc234_d

```python:提出
# 入力の受け取り
N,K=map(int,input().split())
P=list(map(int,input().split()))

# heapqのインポート
import heapq

# (1)heap queueを用意する
que=[]
 
# (2)P1~PKをheap queueへ入れる
for i in range(K):
    heapq.heappush(que,P[i])

# (3)heap queueの最小値を出力する
print(que[0])

# i=K~(N-1)
for i in range(K,N):
    # (4)heap queueから最小値を取り出す
    x=heapq.heappop(que)
    # (5)(heap queueの最小値)とPiのうち大きい方をheap queueへ戻す
    heapq.heappush(que,max(x,P[i]))
    # (6)(heap queueの最小値)を出力する
    print(que[0])
    # (7)次のiへ((4)へ戻る)
```

# 26 deque ABC237 D Dif:544

https://atcoder.jp/contests/abc237/tasks/abc237_d

```python:提出
# 入力の受け取り
N=int(input())
S=input()

# deque のインポート
from collections import deque

# キューを用意
que=deque()

# Nを追加
que.append(N)

# i=(N-1)~0 -1ずつ
for i in range(N-1,-1,-1):
    # Sのi文字目が「R｣
    if S[i]=="R":
        # 先頭(左端)へ「i」を追加
        que.appendleft(i)
    # そうでない場合(Sのi文字目が「L」)
    else:
        # 末端(右端)へ「i」を追加
        que.append(i)  

# 答えの出力
# ([]がいらない場合は先頭に「*」をつける)
print(*que)
```

# 27 DP1 ABC211 C Dif:559

https://atcoder.jp/contests/abc211/tasks/abc211_c

```python:提出
# 入力の受け取り
S=input()
# 文字数=N
N=len(S)

# Sの0文字目を?にする
S="?"+S
# T=?chokudai(?は0文字目)
T="?chokudai"

# 余りの定義
mod=10**9+7

# (1)表を作る
dp=[[0]*9 for i in range(N+1)]
 
# (2)すぐにわかるところを埋める
# i=0~N
for i in range(N+1):
    # k=0
    dp[i][0]=1

# (3)表の小さい方から答えにたどり着くまで埋める
# Sのi文字目までを使う
for i in range(1,N+1):
    # chokudaiのk文字目までを作る
    for k in range(1,9):
        # 1≤i≤N,1≤k≤8,Sのi文字目=chokudaiのk文字目の場合
        if S[i]==T[k]:
            # dp[i-1][k]：Sの(i-1)文字目までを使ってchokudaiのk文字目を作る場合(Sのi文字目を使わない)
            # dp[i-1][k-1]：Sの(i-1)文字目までを使ってchokudaiの(k-1)文字目を作る場合(Sのi文字目を使う)
            dp[i][k]=dp[i-1][k]+dp[i-1][k-1]
 
        # 1≤i≤N,1≤k≤8,Sのi文字目≠chokudaiのk文字目の場合
        else:
            # dp[i-1][k-1]：Sの(i-1)文字目までを使ってchokudaiの(k-1)文字目を作る場合(Sのi文字目を使う)
            dp[i][k]=dp[i-1][k]
                   
    # 余りを取る
    dp[i][k]%=mod

# SのN文字目までを使ってchokudaiの8文字目までを作る方法の数
print(dp[N][8])
```

# 28 全探索2 ABC233 C Dif:604

https://atcoder.jp/contests/abc233/tasks/abc233_c

```python:提出
# 入力の受け取り
N,X=list(map(int,input().split()))

# L,aの格納リスト
L=[]
a=[]

# N回
for i in range(N):
    # 一旦リストで受け取り
    tmp=list(map(int,input().split()))
    # リストの0番目=L
    L.append(tmp[0])
    # リストの1番目~=a
    a.append(tmp[1:])

# 全ての掛け算パターンの結果
Pro=[1]

# i=0~(N-1)
for i in range(N):
    # 一時的に結果を格納するリスト
    tmpPro=[]

    # i番目の袋のa全てについて
    for ai in a[i]:
        # ここまでの全ての掛け算パターンの結果
        for p in Pro:
            # 掛け算して格納
            tmpPro.append(ai*p)

    # ProをtmpProで更新
    Pro=tmpPro

# 結果がXとなったパターンを数える
ans=Pro.count(X)

# 答えを出力
print(ans)
```

# 29 BFS1 ABC204 C Dif:629

https://atcoder.jp/contests/abc204/tasks/abc204_c

```python:提出
# 入力の受け取り
N,M=map(int, input().split())

# 道路の情報を格納するリスト
connect=[[] for i in range(N+1)]

# M回受け取り
for i in range(M):
    # 入力の受け取り
    A,B=map(int, input().split())
    # connect[A]にBを追加
    # 都市1から都市2,3,4にいけるならconnect[1]=2,3,4
    connect[A].append(B)

# dequeをインポート
from collections import deque

# BFS
# 引数：スタート都市→返り値：スタート都市から行ける都市の数
def BFS(start):
    # 行ける都市を数える変数
    # スタート都市→スタート都市には必ず行けるから1
    count=1

    # 訪問済み都市のリスト
    # 訪問済みならTrue、未訪問ならFalse
    visited=[False]*(N+1)

    # スタート都市は訪問済みにする
    visited[start]=True

    # キューを用意
    que=deque()
    # キューへスタート都市を追加
    que.append(start)
  
    # キューが空になるまで
    while 0<len(que):
        # 今いる都市
        now=que.popleft()

        # 今いる都市から行ける都市を順にtoへ
        for to in connect[now]:
            # もしtoが未訪問なら
            if visited[to]==False:
                # countにプラス1
                count+=1

                # toを訪問済みにする
                visited[to]=True

                # キューへtoを追加
                que.append(to)

    # 行ける都市の数を返す
    return count

# 答えを格納する変数
ans=0

# x=1~N
for x in range(1,N+1):
    # xをスタート地点としたときに行ける都市の数を順に足し算
    ans+=BFS(x)

# 答えの出力
print(ans)
```

# 30 規則性利用 ABC238 C Dif:637

https://atcoder.jp/contests/abc238/tasks/abc238_c

```python:提出
# 余りを定義
mod=998244353

# 入力の受け取り
N=int(input())

# A~Bまでの和
# 引数：A,B→返り値：A~Bまでの和
def S(A,B):
    return (B-A+1)*(A+B)//2

# 答え
ans=0

# x~1~18
for x in range(1,19):
    # 10^x≤Nならば
    if 10**x<=N:
        # 「1~9*10**(x-1)までの和」
        ans+=S(1,9*10**(x-1))
        # 余りを取る
        ans%=mod
    # 10^(x-1)≤N<10^xならば
    else:
        # 「1～(N-10^(x-1)+1)までの和」
        ans+=S(1,N-10**(x-1)+1)
        # 余りを取る
        ans%=mod
        # forを抜ける
        break

# 答えの出力
print(ans)
```

# 31 全探索3 ABC227 C Dif:692

https://atcoder.jp/contests/abc227/tasks/abc227_c

```python:提出
# pypyで提出

# 入力の受け取り
N=int(input())

# 答えのカウント
ans=0

# 初期値
A=1
# A≤(Nの三乗根)⇔A^3≤Nの間
while A**3<=N:
    # 初期値
    B=A
    # B≤√(N/A)⇔A*B^2≤Nの間
    while A*B**2<=N:
        # ありうるCの個数=(N/AB)の切り捨て-B+1
        ans+=int(N/(A*B))-B+1
        # 次のBへ
        B+=1
    # 次のAへ
    A+=1

# 答えの出力
print(ans)
```

# 32 DFS1 ABC213 D Dif:710

https://atcoder.jp/contests/abc213/tasks/abc213_d

```python:提出
# 再帰回数上限。再帰関数を書くときは必ず最初に書くこと
import sys
sys.setrecursionlimit(10**6)

# 入力受け取り
N=int(input())

# 辺の情報格納
connect=[[] for i in range(N+1)]

# 辺の情報受け取り
for i in range(N-1):
    A,B=map(int, input().split())
    connect[A].append(B)
    connect[B].append(A)
# connect[1]=[2,3,4]ならば1と2,3,4がつながっている、というように確認できる

# 小さい順に回るからソート
for i in range(N+1):
    connect[i].sort()

# 答えの格納リスト
ans=[]

# DFS(今いる都市,前にいた都市)
def DFS(now,pre):
    # 今いる都市を答えに入れる
    ans.append(now)
    # to=今いる都市から行ける都市
    for to in connect[now]:
        # もしtoが前にいた都市と違うなら
        if to!=pre:
            # 更に先へ探索する
            DFS(to,now)
            # 戻ってきたら答えへ格納
            ans.append(now)

# 最初の都市=1,前にいた都市=-1(前にいた都市がないので存在しない番号)としてスタート
DFS(1,-1)

# 答えの出力
print(*ans)
```

# 33 連想配列2 ABC218 D Dif:715

https://atcoder.jp/contests/abc218/tasks/abc218_d

```python:提出
# 入力を受け取り
N=int(input())

# 座標の格納用リスト
points=[]

# defaultdictを用意 初期値は0
from collections import defaultdict
# (x,y)が存在したらp[(x,y)]=1
p=defaultdict(int)

# M行受け取り
for i in range(N):
    # x,yを受け取り
    x,y=map(int, input().split())
    # 座標をpointsへ格納
    points.append([x,y])
    # p[(x,y)]=1を記録
    p[(x,y)]=1

# 答えを格納する変数
ans=0

# p1=0~(N-1)
for p1 in range(N):
    # p2=(p1+1)~(N-1)
    for p2 in range(p1+1,N):
        # p1のx座標,y座標
        p1_x,p1_y=points[p1]
        # p1のx座標,y座標
        p2_x,p2_y=points[p2]
 
        # x座標またはy座標が同じ場合は
        if p1_x==p2_x or p1_y==p2_y:
            # 次の点へ
            continue
        # 座標(p1_x,p2_y)と座標(p2_x,p1_y)の点が存在すれば
        if p[(p1_x,p2_y)]==1 and p[(p2_x,p1_y)]==1:
            # 答えにプラス1
            ans+=1

# 二重に数えているので2で割る
ans//=2
# 答えを出力
print(ans)
```

# 34 UnionFind1 ATC B

https://atcoder.jp/contests/atc001/tasks/unionfind_a

```python:提出
class UnionFind:
    def __init__(self,n):
        self.n=n
        self.parent_size=[-1]*n
    def leader(self,a):
        if self.parent_size[a]<0: return a
        self.parent_size[a]=self.leader(self.parent_size[a])
        return self.parent_size[a]
    def merge(self,a,b):
        x,y=self.leader(a),self.leader(b)
        if x == y: return
        if abs(self.parent_size[x])<abs(self.parent_size[y]):x,y=y,x
        self.parent_size[x] += self.parent_size[y]
        self.parent_size[y]=x
    def same(self,a,b):
        return self.leader(a) == self.leader(b)
    def size(self,a):
        return abs(self.parent_size[self.leader(a)])
    def groups(self):
        result=[[] for _ in range(self.n)]
        for i in range(self.n):
            result[self.leader(i)].append(i)
        return [r for r in result if r != []]
 
# 入力の受け取り
N,Q=map(int,input().split())
 
# UnionFindを用意
UF=UnionFind(N+1)
 
# Q回
for i in range(Q):
    # 入力の受け取り
    P,A,B=map(int,input().split())
 
    # P=0の場合
    if P==0:
        # A,Bを連結
        UF.merge(A,B)
   
    # P=1の場合
    else:
        # A,Bが連結なら
        if UF.same(A,B):
            # 「Yes」を出力
            print("Yes")
        # 連結でないなら
        else:
            # 「No」を出力
            print("No")
```

# 35 UnionFind2 ABC231 D Dif:726

https://atcoder.jp/contests/abc231/tasks/abc231_d

```python:提出
class UnionFind:
    def __init__(self,n):
        self.n=n
        self.parent_size=[-1]*n
    def leader(self,a):
        if self.parent_size[a]<0: return a
        self.parent_size[a]=self.leader(self.parent_size[a])
        return self.parent_size[a]
    def merge(self,a,b):
        x,y=self.leader(a),self.leader(b)
        if x == y: return
        if abs(self.parent_size[x])<abs(self.parent_size[y]):x,y=y,x
        self.parent_size[x] += self.parent_size[y]
        self.parent_size[y]=x
    def same(self,a,b):
        return self.leader(a) == self.leader(b)
    def size(self,a):
        return abs(self.parent_size[self.leader(a)])
    def groups(self):
        result=[[] for _ in range(self.n)]
        for i in range(self.n):
            result[self.leader(i)].append(i)
        return [r for r in result if r != []]

# 入力の受け取り
N,M=map(int,input().split())

# UnionFind 初期化
UF=UnionFind(N+1)

# 辺の本数をカウント
count=[0]*(N+1)

# M回
for i in range(M):
    # 入力の受け取り
    A,B=map(int,input().split())

    # 辺の本数をカウント
    count[A]+=1
    count[B]+=1
   
    # 辺の本数が3本以上なら
    if 3<=count[A] or 3<=count[B]:
        # 「No」を出力
        print("No")
        # 終了
        exit()

    # A,Bが連結の場合
    if UF.same(A,B)==True:
        # 「No」を出力
        print("No")
        # 終了
        exit()

    # そうでなければ(連結出ない場合)
    else:
        # A,Bに辺を張る(連結する)
        UF.merge(A,B)

# 「Yes」を出力
print("Yes")
```

```python:別解
# 再帰回数上限。再帰関数を使うときは必ず最初に書くこと
import sys
sys.setrecursionlimit(10**6)

# 入力の受け取り
N,M=map(int,input().split())

# つながっている頂点の記録
Connect=[[] for i in range(N+1)]

# M回
for i in range(M):
    # 入力の受け取り
    A,B=map(int,input().split())

    # A→B、B→Aへ行ける
    Connect[A].append(B)
    Connect[B].append(A)
 
    # 辺の本数が3本以上なら
    if 3<=len(Connect[A]) or 3<=len(Connect[B]):
        # 「No」を出力
        print("No")
        # 終了
        exit()

# まだ訪問済みでない頂点
visited=[False]*(N+1)

# DFS(今いる頂点、直前にいた頂点)
def DFS(Now,Pre):
    # 今いる頂点を訪問済みにする
    visited[Now]=True

    # to=Nowから行ける頂点
    for to in Connect[Now]:
        # 直前にいた頂点でなければ
        if to!=Pre:
            # 訪問済みでなければ
            if visited[to]==False:
                # 次のDFSを開始
                DFS(to,Now)
            # 訪問済みであれば
            # ⇔ループになった
            else:
                # 「No」を出力
                print("No")
                # 終了
                exit()                

# i=1~N
for i in range(1,N+1):
    # 訪問済みでなければ
    if visited[i]==False:
        # DFSを開始
        # (直前にいた頂点はないので0にしておく)
        DFS(i,0)

# 「Yes」を出力
print("Yes")
```

# 36 尺取法1、区間和 ABC229 D Dif:745

https://atcoder.jp/contests/abc229/tasks/abc229_d

```python:提出
# 入力の受け取り
S=input()
K=int(input())

S="?"+S

# Sの長さ
N=len(S)

# 「.」の累積個数
Count=[0]*N

# i=1~(N-1)
for i in range(1,N):
    # S[i]=「X」ならば
    if S[i]=="X":
        # 一つ左と同じ
        Count[i]=Count[i-1]
    # そうでないなら(S[i]=「.」)
    else:
        # 一つ左+1
        Count[i]=Count[i-1]+1

# 答え
ans=0

# 右
r=1

# l=1~(N-1)
for l in range(1,N):
    # r<Nの間
    while r<N:
        # [左,右]にある「.」の数=Count[r]-Count[l-1]
        Period=Count[r]-Count[l-1]

        # [左,右]にある「.」の数≤Kならば
        # ⇔[左,右]にある「.」を全て「X」に変えられるなら
        if Period<=K:
            # 右を移動
            r+=1
        # そうでないなら([左,右]にある「.」を全て「X」に変えられないなら)
        else:
            # whileを抜ける
            break

    # [左,右-1]の長さを計算し、今までの答えより大きければ更新
    ans=max(ans,r-l)

# 答えの出力
print(ans)
```

# 37 BFS2 ABC211 D Dif:755

https://atcoder.jp/contests/abc211/tasks/abc211_d

```python:提出
# 入力の受け取り
N,M=map(int, input().split())

# 道路の情報を格納する変数
connect=[[] for i in range(N+1)]
# 道路の情報を受け取って格納
for i in range(M):
    A,B=map(int, input().split())
    connect[A].append(B)
    connect[B].append(A)

# 余りの定義
mod=10**9+7

# まだ到達していない都市の移動時間(infinity：無限大)
# 大きめの数にする
inf=10**15

# (1)各都市の最短移動時間を記録するリストtimeを作る(初期値は大きな数)
time=[inf]*(N+1)
# 都市①の最短移動時間は「0」
time[1]=0

# (2)各都市にたどり着くまでの経路数を記録するリストcountを作る
count=[0]*(N+1)
# 都市①に行く経路数は「1」
count[1]=1

# (3)キューを用意
from collections import deque
que=deque()
# キューに都市①を入れる
que.append(1)

# (6)(4)~(5)をキューが空になるまで繰り返す
while 0<len(que):
    # (4)キューの左端から要素(都市の番号)を取り出す(今いる街)
    now=que.popleft()

    # (5)今いる都市から行ける都市を確認する
    # nowから行ける都市を順にtoへ格納
    for to in connect[now]:
        # もし行ける都市の移動時間がinfならば(まだ更新されていない)
        if time[to]==inf:
            # (5-1)「経路数」=「今いる都市の経路数」
            count[to]=count[now]
            # (5-2)「最短移動時間」=「今いる都市の最短移動時間+1」
            time[to]=time[now]+1
            # (5-3)キューに追加
            que.append(to)

        # そうでないなら(移動時間が更新済み)
        else:
            # 「最短移動時間」=「今いる都市の最短移動時間+1」(最短経路)ならば
            if time[to]==time[now]+1:
                # (5-4)「経路数」+=「今いる都市の経路数」
                count[to]+=count[now]

        # 余りを取る
        count[to]%=mod

# (7)答えを出力する
# Nが未到達であれば(「最短移動時間」が更新されていなければ)
if time[N]==inf:
    # たどり着けないため「0」を出力
    print(0)
  
# そうでないならば
else:
    # count[N]を出力
    print(count[N])
```

# 38 シミュレーション2 ABC243 D Dif:758

https://atcoder.jp/contests/abc243/tasks/abc243_d

```python:提出
# 入力の受け取り
N,X=map(int,input().split())
S=input()

# 移動の記録
Move=[]

# i=0~(N-1)
for i in range(N):
    # ・記録が空の場合
    if len(Move)==0:
        # S[i]を記録
        Move.append(S[i])
   
    # ・記録が空でない場合
    else:
        # ・S[i]が「L」または「R」
        if S[i]=="L" or S[i]=="R":
            # S[i]を記録
            Move.append(S[i])
        # ・S[i]が「U」
        else:
            # ・S[i]が「U」かつ記録の末尾が「L」または「R」(「LU」「RU」になる場合)
            if Move[-1]=="L" or Move[-1]=="R":
                # 記録の末尾を消す
                Move.pop()
            # ・S[i]が「U」かつ記録の末尾が「U」
            else:
                # 「U」を記録
                Move.append("U")

# シミュレーション
for s in Move:
    # 「L」ならば2Xへ移動
    if s=="L":
        X*=2
    # 「R」ならば(2X+1)へ移動
    elif s=="R":
        X=2*X+1
    # 「U」ならばX//2へ移動
    else:
        X//=2

# 答えの出力
print(X)
```

# 39 DP2 ABC248 C Dif:787

https://atcoder.jp/contests/abc248/tasks/abc248_c

```python:提出
# pypyで提出

# 入力の受け取り
N,M,K=map(int,input().split())

# 余りの定義
mod=998244353

# (1)表を作る
dp=[[0]*(K+1) for i in range(N+1)]

# (2)すぐにわかるところを埋める
# ・(x≤M)dp[1][x]=1
# ・(M<x)dp[1][x]=0
for x in range(1,M+1):
    dp[1][x]=1

# (3)表の小さい方から答えにたどり着くまで埋める
# i=2~N
for i in range(2,N+1):
    # x=1~K
    for x in range(1,K+1):
        # j=1~(x-1)
        for j in range(1,x):
            # ・(2≤i,1≤j≤x-1)x-j≤Mならばdp[i][x]+=dp[i-1][j]
            if x-j<=M:
                dp[i][x]+=dp[i-1][j]
                # 余りを取る
                dp[i][x]%=mod

# (4)答えを出力する
# 答え
ans=0

# x=1~K
for x in range(1,K+1):
    # dp[N][1]~dp[N][K]の和
    ans+=dp[N][x]
    # 余りを取る
    ans%=mod

# 答えを出力
print(ans)
```

# 40 二分探索2 ABC248 D Dif:793

https://atcoder.jp/contests/abc248/tasks/abc248_d

```python:提出
# pypyで提出
 
# 入力の受け取り
N=int(input())
A=list(map(int,input().split()))
 
# 1,2,3,...が何番目にあるかの記録 左端には「0」を入れておく
Aindx=[[0] for i in range(10**6)]
 
# i=0~(N-1)
for i in range(N):
    # インデックス番号を記録
    # 1インデックスなので「i+1」を記録することに注意
    Aindx[A[i]].append(i+1)
 
# i=0~(N-1)
for i in range(10**6):
    # 右端に∞=10^6を追加
    Aindx[i].append(10**6)
 
# Xがあるインデックス番号のうちL以上で最小のもの
def NibutanLeft(X,L):
    # (1)左=区間の最小、右=区間の最大とする
    # 左
    l=0
    # 右(=長さ-1)
    r=len(Aindx[X])-1
 
    # (4)1<(右-左)となっている間(2)~(4)を繰り返す
    while 1<r-l:
        # (2)中央=(左+右)//2が条件を満たすか確認
        # 中央=(左+右)//2
        c=(l+r)//2
 
        # (3)(2)の結果より左または右を更新する
        # ・(中央)番目の数がL以上
        if L<=Aindx[X][c]:
            # 左=中央と更新
            r=c
        # ・(中央)番目の数がLより小さい
        else:
            # 右=中央と更新
            l=c
 
    # 右を返す
    return r
 
# Xがあるインデックス番号のうちR以下で最大のもの
def NibutanRight(X,R):
    # (1)左=区間の最小、右=区間の最大とする
    # 左
    l=0
    # 右(=長さ-1)
    r=len(Aindx[X])-1
 
    # (4)1<(右-左)となっている間(2)~(4)を繰り返す
    while 1<r-l:
        # (2)中央=(左+右)//2が条件を満たすか確認
        # 中央=(左+右)//2
        c=(l+r)//2
 
        # (3)(2)の結果より左または右を更新する
        # ・(中央)番目の数がR以下
        if Aindx[X][c]<=R:
            # 左=中央と更新
            l=c
        # ・(中央)番目の数がRより大きい
        else:
            # 右=中央と更新
            r=c
 
    # 右を返す
    return l
 
# 入力の受け取り
Q=int(input())

# Q回
for i in range(Q):
    # 入力の受け取り
    L,R,X=map(int,input().split())
 
    # 「Xがあるインデックス番号のうちL以上で最小のもの」
    Lindx=NibutanLeft(X, L)
    # 「Xがあるインデックス番号のうちR以下で最大のもの」
    Rindx=NibutanRight(X, R)
    # 答えを出力
    print(Rindx-Lindx+1)
```

```python:別解
# 入力の受け取り
N=int(input())
A=list(map(int,input().split()))

# 1,2,3,...が何番目にあるかの記録 左端には「0」を入れておく
Aindx=[[0] for i in range(10**6)]

# i=0~(N-1)
for i in range(N):
    # インデックス番号を記録
    # 1インデックスなので「i+1」を記録することに注意
    Aindx[A[i]].append(i+1)

# i=0~(N-1)
for i in range(10**6):
    # 右端に∞=10^6を追加
    Aindx[i].append(10**6)

# 入力の受け取り
Q=int(input())

# bisectをインポート
import bisect

# Q回
for i in range(Q):
    # 入力の受け取り
    L,R,X=map(int,input().split())

    # Lを大小関係を保ったままリストに挿入する位置のインデックス(同じ数があれば左側へ)
    Lindx=bisect.bisect_left(Aindx[X], L)
    # Rを大小関係を保ったままリストに挿入する位置のインデックス(同じ数があれば右側へ)
    Rindx=bisect.bisect_right(Aindx[X], R)
    # 答えを出力
    print(Rindx-Lindx)
```

# 41 尺取法2、エラトステネスの篩 ABC250 D Dif:797

https://atcoder.jp/contests/abc250/tasks/abc250_d

```python:提出
# エラトステネスの篩
def Eratosthenes(N):
    # 素数であるかの判定リスト
    IsPrime=[True]*(N+1)

    # i=2,3,4,...
    i=2
    # i≤√Nまで⇔i^2≤Nまで
    while i**2<=N:
        # iが素数でなければ
        if IsPrime[i]==False:
            # 次のiへ
            i+=1
            continue
       
        # k=2,3,4,...
        k=2
        while i*k<=N:
            # iの倍数は素数でない
            IsPrime[i*k]=False
            # 次のkへ
            k+=1

        # 次のkへ
        i+=1

    # 素数リスト
    PList=[]

    # i=2~N
    for i in range(2,N+1):
        # iが素数ならば
        if IsPrime[i]==True:
            # リストへ入れる
            PList.append(i)

    # リストを返す
    return PList

# 入力の受け取り
N=int(input())
# 10^6以下の素数リストを作成
P=Eratosthenes(10**6)

# 答え
ans=0

# 素数リストの長さ
lenP=len(P)

# 最後の素数の番号(0インデックス)
k=lenP-1

# i=0~(lenP-1)
for i in range(lenP):
 
    # p=i番目の素数(0インデックス)
    # q=k番目の素数(0インデックス)
    # p*q^3≤Nとなるまでkを減らしていく
    while i<k and N<P[i]*P[k]**3:
        k-=1

    # k≤iとなったら
    if k<=i:
        # 答えの出力
        print(ans)
        # 途中終了
        exit()

    # i+1,i+2,...,k番目の素数までqとして使用できる
    # ⇔(k-i)個
    ans+=k-i
```

```python:別解
def Eratosthenes(N):
    IsPrime=[True]*(N+1)
 
    i=2
    while i**2<=N:
        if IsPrime[i]==False:
            i+=1
            continue
       
        k=2
        while i*k<=N:
            IsPrime[i*k]=False
            k+=1
 
        i+=1
 
    PList=[]
 
    for i in range(2,N+1):
        if IsPrime[i]==True:
            PList.append(i)
 
    return PList

# 入力の受け取り
N=int(input())
# 素数リストを作る
P=Eratosthenes(10**6)

# 素数リストの長さ
lenP=len(P)

# 二分探索
def Nibutan(i):
    # 左
    l=0
    # 右
    r=lenP-1

    # 1<(右-左)ならば
    while 1<(r-l):
        # 中央=(左+右)//2
        c=(l+r)//2

        # P[i]=i番目の素数
        # P[c]=c番目の素数
        # 条件を満たすなら
        if P[i]*P[c]**3<=N:
            # 左=中央と更新
            l=c
        # 条件を満たさないなら
        else:
            # 右=中央と更新
            r=c

    # 左を返す
    return l

# 答え
ans=0

# i=0~(素数リストの長さ-1)
for i in range(lenP):
    # P[i]*P[k]^3≤Nとなるもののうち最大のk
    k=Nibutan(i)
    # i<kならば
    if i<k:
        # (k-i)個プラス
        ans+=k-i
    # そうでないなら
    else:
        # 探索終了
        break

# 答えを出力
print(ans)
```

# 42 FenwickTree ACL B

https://atcoder.jp/contests/practice2/tasks/practice2_b

```python:提出
class FenwickTree:
    def __init__(self,N):
        self.N=N
        self.F=[0]*N
 
    def add(self,i,x):
        i+=1
        while i<=self.N:
            self.F[i-1]+=x
            i+=i&-i
 
    def sum_r(self,r):
        s=0
        while 0<r:
            s+=self.F[r-1]
            r-=r&-r
        return s
 
    def sum(self,l,r):
        return self.sum_r(r+1)-self.sum_r(l)
 
    def select(self,i):
        return self.sum(i,i)
 
# 入力の受け取り
N,Q=map(int,input().split())
a=list(map(int,input().split()))
 
# 長さ(N+1)のFenwickTreeを用意
# 初期値は全て0
FT=FenwickTree(N+1)
 
# i=0~(N-1)
for i in range(N):
    # i番目にa[i]を足す
    FT.add(i, a[i])
 
# Q回
for i in range(Q):
    # 入力の受け取り
    q,a,b=map(int,input().split())
 
    # q=0の場合
    if q==0:
        # a番目にbを足す(p番目にxを足す)
        FT.add(a, b)
    # q=1の場合
    else:
        # a~(b-1)番目の区間和を出力(l~(r-1)番目の区間和を出力)
        print(FT.sum(a, b-1))
```

# 43 想定解multiset ABC217 D Dif:802

https://atcoder.jp/contests/abc217/tasks/abc217_d

```python:提出
# 提出はpypyで行う

# Fenwick_Tree
class Fenwick_Tree:
    def __init__(self,n):
        self._n=n
        self.data=[0]*n
    def add(self,p,x):
        p+=1
        while p<=self._n:
            self.data[p-1] +=x
            p+=p&-p
    def _sum(self,r):
        s=0
        while 0<r:
            s+=self.data[r-1]
            r-=r&-r
        return s
    def sum(self,l,r):
        r+=1
        return self._sum(r)-self._sum(l)
    def select(self,p):
        return self.sum(p,p)

# 入力の受け取り
L,Q=map(int, input().split())

# クエリの記録用リスト
query=[]

# カットする場所を予め記録するリスト
cut=[]

# Q回
for i in range(Q):
    # 入力の受け取り
    c,x=map(int, input().split())
    # クエリを記録
    query.append([c,x])
    # c=1ならば
    if c==1:
        # cutに場所を記録
        cut.append(x)

# cutに「0」を追加
cut.append(0)
# cutに「L」を追加
cut.append(L)

# cutをソート
cut.sort()

# cutの長さをNとする
N=len(cut)

# x(カットする場所)→インデックス番号への変換
cut_index=dict()

# 変換表の作成
for i in range(N):
    cut_index[cut[i]]=i

# FenwickTreeの作成
Fenwick=Fenwick_Tree(N)

# 左端(0)に「1」を立てる(1を足す)
Fenwick.add(0,1)
# 右端(Lのインデックス番号)に「1」を立てる(1を足す)
Fenwick.add(N-1,1)

# xがどのインデックス番号の間にあるか確認する二分探索
# 引数：x→返り値：cut[l]<x<cut[r]を満たす最大のl、最小のr
def Nibutan_x(x):
    # 左(left)=0
    l=0
    # 右(right)=N-1
    r=N-1

    # 1<(右-左)の間
    while 1<r-l:
        # 中央(center)=(l+r)//2
        c=(l+r)//2
        # cut[c]<xなら
        if cut[c]<x:
            # 左=c
            l=c
        # x<cut[c]なら
        else:
            # 右端=c
            r=c

    # 左、右を返す
    return l,r

# xより左で1が立っている場所のうち、一番近いものを二分探索
# 引数：x→返り値：Fenwickの区間和[k~x]が1以上となるもののうち、最大のk
def Nibutan_l(x):
    # 左(left)=0
    l=0
    # 右(right)=x
    r=x

    # 1<(右-左)の間
    while 1<r-l:
        # 中央(center)=(l+r)//2
        c=(l+r)//2
        # 区間和[c~x]が1以上
        # ⇔区間c~xに「1」が1つ以上立っている
        if 1<=Fenwick.sum(c,x):
            # 左=中央
            l=c
        # 区間和[c~x]が1未満(=0)
        # ⇔区間c~xに「1」が立っていない
        else:
            # 右=中央
            r=c

    # 区間和[r~x]が1ならば
    if Fenwick.sum(r,x)==1:
        # rを返す
        return r
    # そうでなければ
    else:
        # lを返す
        return l

# xより右で1が立っている場所のうち、一番近いものを二分探索
# 引数：x→返り値：Fenwickの区間和[x~k]が1以上となるもののうち、最小のk
def Nibutan_r(x):
    # 左(left)=x
    l=x
    # 右(right)=N-1
    r=N-1

    # 1<(右-左)の間
    while 1<r-l:
        # 中央(center)=(l+r)//2
        c=(l+r)//2
        # 区間和[x~c]が1以上
        # ⇔区間x~cに「1」が1つ以上立っている
        if 1<=Fenwick.sum(x,c):
            # 右=中央
            r=c
        # 区間和[x~c]が1未満(=0)
        # ⇔区間x~cに「1」が立っていない
        else:
            # 左=中央
            l=c

    # 区間和[x~l]が1ならば
    if Fenwick.sum(x,l)==1:
        # lを返す
        return l
    # そうでなければ
    else:
        # rを返す
        return r

# クエリを読み込み
for c,x in query:
    # c=1の場合
    if c==1:
        # cut_index[i]の部分に「1」を立てる(+1する)
        Fenwick.add(cut_index[x],1)
    # c=2の場合
    else:
        # xがどのインデックス番号の間にあるか確認する二分探索
        l_x,r_x=Nibutan_x(x)
        # xより左で「1」が立っている場所のうち、一番近い場所のインデックス番号を二分探索
        l_index=Nibutan_l(l_x)
        # xより右で「1」が立っている場所のうち、一番近い場所のインデックス番号を二分探索
        r_index=Nibutan_r(r_x)
        # 右の値-左の値
        print(cut[r_index]-cut[l_index])
```

```python:別解
import bisect
from array import array

# 入力の受け取り
L,Q=map(int,input().split())

# カット位置を記録するarray
# array(型コード,値)
cut=array("i",[0,L])

# Q回
for i in range(Q):
    # 入力の受け取り
    c,x=map(int,input().split())
    # c=1の場合
    if c==1:
        # xをx以上で最小の要素の次に挿入
        bisect.insort(cut,x)
    # それ以外(c=2の場合)
    else:
        # x以上で最小の要素のインデックス番号を取得
        index=bisect.bisect(cut,x)
        # 長さを出力
        print(cut[index]-cut[index-1])
```

# 44 DP3 ABC204 D Dif:832

https://atcoder.jp/contests/abc204/tasks/abc204_d

```python:提出
# pypyで提出

# 入力の受け取り
N=int(input())
# Tは先頭に[0]を追加して受け取り
T=[0]+list(map(int, input().split()))

# Tの合計
T_sum=sum(T)

# (1)表を作る
# 『i番目までの数を組み合わせてKを作れるか』
# 例：『3番目までの数を組み合わせて「7」を作れる』→ dp[3][7]=True
dp=[[False]*(T_sum+1) for i in range(N+1)]

# (2)すぐにわかるところを埋める
# 『0番目までの数を組み合わせて「0」を作れる
dp[0][0]=True

# (3)表の小さい方から答えにたどり着くまで埋める
# i=1~N
for i in range(1,N+1):
    # K=0~T_sum Kを作れるか確認
    for K in range(T_sum+1):
        # 『(i-1)番目までの数を組み合わせてKを作れる』(→dp[i-1][K]=True)ならば
        if dp[i-1][K]==True:
            # 『i番目までの数を組み合わせてKを作れる』(→dp[i][K]=True)
            dp[i][K]=True
        # 0<=K-T[i] かつ『(i-1)番目までの数を組み合わせてK-T[i]を作れる』ならば(dp[i-1][K-T[i]]=True)
        if 0<=K-T[i] and dp[i-1][K-T[i]]==True:
            # 『i番目までの数を組み合わせてKを作れる』(→dp[i][K]=True)            
            dp[i][K]=True

# 答えを格納する変数(初期値はバカでかい数)
ans=10**15

# (4)答えを出力する
# K=0~T_sum
for K in range(T_sum+1):
    # 『N番目までの数を組み合わせてKを作れる』ならば
    if dp[N][K]==True:
        # max(K,T_sum-K)が料理をすべて作るのにかかる時間=答えの候補
        # それまでのansより小さければ更新
        ans=min(ans,max(K,T_sum-K))

# 答えの出力
print(ans)
```

# 45 区間スケジューリング ABC230 D Dif:963

https://atcoder.jp/contests/abc230/tasks/abc230_d

```python:提出
# 入力の受け取り
N,D=map(int,input().split())

# 区間の情報
Section=[]

# N回
for i in range(N):
    # 入力の受け取り
    L,R=map(int,input().split())
    # 情報を格納
    Section.append([L,R])

# 右端の列番号を基準にソート
Section.sort(key=lambda x:x[1])

# 最初の壁の右端にパンチを打つ
X=Section[0][1]

# 答え
ans=1

# i=1~(N-1)
for i in range(1,N):
    # i番目の壁の左端、右端
    Li,Ri=Section[i][0],Section[i][1]
    # 最後のパンチでi番目の壁を壊せていなければ
    # ⇔最後にパンチした位置+(D-1)<左端
    if X+D-1<Li:
        # 右端にパンチを打つ
        X=Ri
        # 回数をカウント
        ans+=1

# 答えの出力
print(ans)
```

# 46 UnionFind3 ABC218 E Dif:1004

https://atcoder.jp/contests/abc218/tasks/abc218_e

```python:提出
# UnionFind
class UnionFind:
    def __init__(self,n):
        self.n=n
        self.parent_size=[-1]*n
    def leader(self,a):
        if self.parent_size[a]<0: return a
        self.parent_size[a]=self.leader(self.parent_size[a])
        return self.parent_size[a]
    def merge(self,a,b):
        x,y=self.leader(a),self.leader(b)
        if x == y: return
        if abs(self.parent_size[x])<abs(self.parent_size[y]):x,y=y,x
        self.parent_size[x] += self.parent_size[y]
        self.parent_size[y]=x
    def same(self,a,b):
        return self.leader(a) == self.leader(b)
    def size(self,a):
        return abs(self.parent_size[self.leader(a)])  
    def groups(self):
        result=[[] for _ in range(self.n)]
        for i in range(self.n):
            result[self.leader(i)].append(i)
        return [r for r in result if r != []]

# 入力の受け取り
N,M=map(int, input().split())

# 辺の情報格納用リスト
edge=[]

# M行受け取り
for i in range(M):
    A,B,C=map(int, input().split())
    # 後のソートのためC先頭で格納
    edge.append([C,A,B])

# (1)辺をCの小さい順に並び替える
edge.sort()

# 報酬
ans=0

# (2)すべての辺を取り除き、報酬と罰金の合計を計算する
for i in range(M):
    ans+=edge[i][0]

# UnionFindを初期化(頂点数(N+1)個(0~N))
UF=UnionFind(N+1)

# edgeの各要素について
for C,A,B in edge:
    # (3)Cが小さい方から辺を確認していく
    # ・Cが0以下なら
    if C<=0:
        # 頂点Ai,Biを連結し、罰金|C|を報酬にプラスする(Cがマイナスの辺は取り除く理由がない)
        # 連結
        UF.merge(A,B)
        # 罰金=|C|をプラス
        ans+=abs(C)

    # そうでないならば(cが0より大きいなら)
    else:
        # ・頂点Ai,Biが非連結なら
        if UF.same(A,B)==False:
            # 頂点Ai,Biを連結し、報酬からCを引く
            # 報酬からCを引く
            ans-=C
            # A,Bを連結
            UF.merge(A,B)

# 答えを出力
print(ans)
```

# 47 DFS2 ABC239 E Dif:1084

https://atcoder.jp/contests/abc239/tasks/abc239_e

```python:提出
# 入力の受け取り
N,Q=map(int,input().split())
# 1インデックスにするため先頭に「0」を追加
X=[0]+list(map(int,input().split()))
# 辺の情報格納用
edge=[[] for i in range(N+1)]

# (N-1)回
for i in range(N-1):
    # 入力の受け取り
    A,B=map(int,input().split())
    # 辺の情報を格納
    edge[A].append(B)
    edge[B].append(A)

# 部分木の頂点に書いている数を大きい順に格納したリスト
# 1インデックスにするため0番目は埋めておく
P=[[0]]

# (1)「部分木に含まれる数を大きい順にソートした二次元配列」をPとし、自分自身に書いている数をPへ記録する
for i in range(1,N+1):
    # Pへ自分自身に書いている数を追加
    P.append([X[i]])

# (2)キューを用意する
que=list()

# (3)スタート地点=頂点①をキューへ入れる
# (今いる頂点,今いる頂点の親,訪問回数)
que.append((1,0,1))

# (4)キューが空になるまで(3)を繰り返す
while 0<len(que):
    # (4)キューの「右端から」要素を取り出す
    # (今いる頂点,今いる頂点の親,訪問回数)
    now,parent,count=que.pop()

    # ・1回目の訪問ならば
    if count==1:
        # (4-1)「今いる頂点」を2回目の訪問としてキューへ記録
        que.append((now,parent,2))
        # (4-2)「今いる頂点から行ける(親でない)頂点」をキューへ1回目の訪問として記録
        # to：今いる頂点から行ける頂点
        for to in edge[now]:
            # 親でなければ
            if to!=parent:
                # キューへ記録
                que.append((to,now,1))

    # ・2回目の訪問ならば
    else:
        # to：今いる頂点から行ける頂点
        for to in edge[now]:
            # (4-3)「今いる頂点」のPへ子の頂点のPを追加
            # 親ならば
            if to==parent:
                # 次の頂点へ
                continue
            P[now]+=P[to]
            # (4-4)大きい順にソート
            P[now].sort(reverse=True)
            # (4-5)20番目以降の要素を捨てる
            P[now]=P[now][:20]

# Q回
for i in range(Q):
    # 入力の受け取り
    V,K=map(int,input().split())
    # Kをマイナス1(P[v]は先頭が0番目、次が1番目、...のため)
    K-=1
    # 答えを出力
    print(P[V][K])
```

# 48 DP4 ABC219 D Dif:1085

https://atcoder.jp/contests/abc219/tasks/abc219_d

```python:提出
# pypyで提出

# 入力の受け取り
N=int(input())
X,Y=map(int, input().split())

# バカでかい数を作っておく(infinity)
inf=10**15

# (1)表を作る
# dp[i][x][y]：「i種類目までの弁当を使い、x個のたこ焼きとy個のたい焼きを手に入れるために必要な弁当の最小個数」
# 初期値はinf
dp=[[[inf]*(Y+1) for i in range(X+1)] for j in range(N+1)]

# (2)すぐにわかるところを埋める
# 「0種類目までの弁当を使い、0個のたこ焼きと0個のたい焼きを手に入れる最小個数」=0
dp[0][0][0]=0

# (3)表の小さい方から答えにたどり着くまで埋める
# i=1~N
for i in range(1,N+1):
    # 入力の受け取り
    A,B=map(int, input().split())
    # たこ焼きの数：x=0~X
    for x in range(X+1):
        # たい焼きの数：y=0~Y
        for y in range(Y+1):
            # 「買わない場合」(すでに埋まっている数のほうが小さい場合は更新しない)      
            dp[i][x][y]=min(dp[i][x][y],dp[i-1][x][y])
 
            # 「買う場合」(すでに埋まっている数のほうが小さい場合は更新しない)
            # たこ焼きの数がX以上→Xへ変換
            x_plus=min(x+A,X)
            # たい焼きの数がY以上→Yへ変換
            y_plus=min(y+B,Y)
            dp[i][x_plus][y_plus]=min(dp[i][x_plus][y_plus],dp[i-1][x][y]+1)

# 答え：「N種類目までの弁当を使い、X個のたこ焼きとY個のたい焼きを手に入れるために必要な弁当の最小個数」
ans=dp[N][X][Y]

# (4)答えを出力する
# もし答えがinfだったら(X個以上のたこ焼き、Y個以上のたい焼きを手に入れられない場合)
if ans==inf:
    # -1を出力
    print(-1)
# そうでないならば
else:
    # 答えを出力
    print(ans)
```

# 49 二分探索3 ABC246 D Dif:1148

https://atcoder.jp/contests/abc246/tasks/abc246_d

```python:提出
# pypyで提出

# 入力の受け取り
N=int(input())

# 関数にする
def f(a,b):
    return a**3+a**2*b+a*b**2+b**3

# 答え
ans=10**20

# b=0,1,2,...10^6
# (10^6より少し大きめにしている)
for b in range(10**6+100):

    # (1)左=区間の最小、右=区間の最大　とする
    # 左
    l=0
    # 右
    r=10**6+100

    # 1<(右-左)の間
    while 1<r-l:
        # (2)中央=(左+右)//2が条件を満たすか確認
        c=(r+l)//2

        # (3)(2)の結果より左または右を更新する
        # 計算結果がN未満なら
        if f(c,b)<N:
            # 左=中央と更新
            l=c
        # 計算結果がN以上なら
        else:
            # 右=中央と更新
            r=c

    # N≤f(l,b)ならば
    if N<=f(l,b):
        # f(l,b)がansより小さければ更新
        ans=min(ans,f(l,b))
    # そうでなければ(f(l,b)<N⇔f(r,b)≤N)
    else:
        # f(r,b)がansより小さければ更新
        ans=min(ans,f(r,b))    

# 答えの出力
print(ans)
```

# 50 ワーシャルフロイド法 ABC208 D Dif:1190

https://atcoder.jp/contests/abc208/tasks/abc208_d

```python:提出
# pypyで提出

# 入力の受け取り
N,M=map(int, input().split())

# 到達不可能時間(大きすぎるとTLEするので注意)
inf=10**15
# 時間表
time=[[inf]*(N+1) for i in range(N+1)]

# i=1~Nまで
for i in range(1,N+1):
    # 都市①→都市①,都市②→都市②、...を時間0へ
    time[i][i]=0

# M回
for i in range(M):
    # 入力の受け取り
    A,B,C=map(int, input().split())
    # 時間表の更新
    time[A][B]=C

# 答えを格納する変数
ans=0

# k=1~N
for k in range(1,N+1):
    # 新しい時間表
    new_time=[[0]*(N+1) for i in range(N+1)]

    # スタート都市：1~N
    for start in range(1,N+1):
        # ゴール都市：1~N
        for goal in range(1,N+1):
            # 新しい時間表を更新
            # 「(K-1)以下の都市を通って良いパターン」と「都市kを経由するパターン」の小さい方
            new_time[start][goal]=min(time[start][goal],time[start][k]+time[k][goal])

           
    # スタート都市：1~N
    for start in range(1,N+1):
        # ゴール都市：1~N
        for goal in range(1,N+1):
             # 新しい時間表でスタート→ゴールが到達不能でなければ
            if new_time[start][goal]!=inf:
                # 新しい時間を答えにプラス
                ans+=new_time[start][goal]
 
    # 古い時間表を新しい時間表へ更新
    time=new_time

# 答えの出力
print(ans)
```

# クラス解説：UnionFind

```python:
# UnionFind
class UnionFind:
    # UnionFind(N)：要素数Nで初期化。
    # 引数：N(要素数)　→　返り値：なし
    def __init__(self,N):
        # 要素数
        self.N=N
        # 根の番号　と　木の要素数
        # マイナスの場合:グループの要素数(自身が根)
        # プラスの場合:根の番号
        self.parent_size=[-1]*N

    # leader(a)：aの根を返す
    # 引数：a　→　返り値：aの根
    def leader(self,a):
        # aが根ならa自身を返す
        if self.parent_size[a]<0: return a
        # aが根でないなら根に向かって木をたどる＋根の更新
        self.parent_size[a]=self.leader(self.parent_size[a])
        # 根を返す
        return self.parent_size[a]

    # merge(a,b)：aとbを連結
    # 引数：a,b　→　返り値：なし
    def merge(self,a,b):
        # a,bの根をx,yへ
        x,y=self.leader(a),self.leader(b)
        # 根が同じなら終了
        if x == y: return
        # 木の要素数を比較　小さい方を大きい方につなげるため
        # x<yならばx,yを入れ替える(xを大きい方にしたい)
        if abs(self.parent_size[x])<abs(self.parent_size[y]):x,y=y,x
        # 要素数の更新：小さい方の要素数を大きい方の要素数に足す
        self.parent_size[x] += self.parent_size[y]
        # 要素数が小さい方の根を大きい方の根につなげる
        self.parent_size[y]=x

    # same(a,b)：aとbの根が同じか確認
    # 引数：a,b　→　返り値：True(根が同じ)　False(根が違う)
    def same(self,a,b):
        # 根を比較し、同じならTrueを返す
        return self.leader(a) == self.leader(b)

    # size(a)：aが属する木の要素数
    # 引数：a　→　返り値：aが属する木の要素数
    def size(self,a):
        # 根の絶対値(=要素数)を返す
        return abs(self.parent_size[self.leader(a)])

    # groups()：それぞれの木の内容を二次元配列として返す
    # 引数：なし　→　返り値：木の内容
    def groups(self):
        # グループの格納リストを作る
        result=[[] for _ in range(self.N)]
        # リストの生成
        for i in range(self.N):
            result[self.leader(i)].append(i)
        # 空の要素を消す
        return [r for r in result if r!=[]]
```

# クラス解説：FenwickTree

```python:
# FenwickTree
class FenwickTree:
    # 「FenwickTree(N)：要素数Nで初期化」
    # 引数：N→返り値：なし
    def __init__(self,N):
        self.N=N
        # F：長さNのリスト
        self.F=[0]*N

    # 「add(i,x)：i番目の要素にxを加算」
    # 引数：i,x→返り値：なし
    def add(self,i,x):
        # 1インデックスにするため1を加算
        i+=1
        # i≤Nの間
        while i<=self.N:
            # xを加算
            # iはプラス1されているのでF[i-1]に加算
            self.F[i-1]+=x
            # 次のi
            i+=i&-i

    # 「sum_r(r)：区間[0,r)の区間和を計算」
    # 引数：r→返り値：区間[0,r)の区間和
    def sum_r(self,r):
        # 合計
        s=0
        # 0<rの間
        while 0<r:
            # sに加算
            s+=self.F[r-1]
            # 次のr
            r-=r&-r
        # 合計を返す
        return s

    # 「sum(l,r)：区間[l,r]の区間和を計算」
    # 引数：l,r→返り値：区間[l,r]の区間和
    def sum(self,l,r):
        # 「区間[l,r]の区間和」=「区間[0,r+1)の区間和」-「区間[0,l)の区間和」
        return self.sum_r(r+1)-self.sum_r(l)

    # 「select(i)：i番目の要素を出力」
    # 引数：i→返り値：i番目の要素
    def select(self,i):
        # 区間[i,i]の区間和
        return self.sum(i,i)
```