結果

問題 No.742 にゃんにゃんにゃん 猫の挨拶
ユーザー 👑 KazunKazun
提出日時 2021-02-10 02:00:41
言語 PyPy3
(7.3.15)
結果
AC  
実行時間 83 ms / 2,500 ms
コード長 3,052 bytes
コンパイル時間 124 ms
コンパイル使用メモリ 82,248 KB
実行使用メモリ 78,016 KB
最終ジャッジ日時 2024-07-07 10:34:33
合計ジャッジ時間 1,361 ms
ジャッジサーバーID
(参考情報)
judge5 / judge3
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 31 ms
53,840 KB
testcase_01 AC 33 ms
53,452 KB
testcase_02 AC 34 ms
54,892 KB
testcase_03 AC 32 ms
53,192 KB
testcase_04 AC 32 ms
54,216 KB
testcase_05 AC 39 ms
60,872 KB
testcase_06 AC 43 ms
63,272 KB
testcase_07 AC 50 ms
68,580 KB
testcase_08 AC 50 ms
70,760 KB
testcase_09 AC 32 ms
53,200 KB
testcase_10 AC 31 ms
53,316 KB
testcase_11 AC 83 ms
78,016 KB
testcase_12 AC 82 ms
77,636 KB
testcase_13 AC 33 ms
52,884 KB
testcase_14 AC 33 ms
53,920 KB
testcase_15 AC 32 ms
54,264 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

class Binary_Indexed_Tree():
    def __init__(self,L,calc,unit,inv,index=1):
        """calcを演算とするN項のBinary Indexed Treeを作成

        calc:演算(2変数関数,群)
        unit:群calcの単位元(xe=ex=xを満たすe)
        inv:群calcの逆元(1変数関数)
        """
        self.calc=calc
        self.unit=unit
        self.inv=inv
        self.index=index

        N=len(L)
        d=max(1,(N-1).bit_length())
        k=2**d

        X=[None]+[unit]*k

        self.num=k
        self.depth=d

        if L:
            for i in range(len(L)):
                p=i+1
                while p<=k:
                    X[p]=self.calc(X[p],L[i])
                    p+=p&(-p)
        self.data=X

    def index(self,k,index=1):
        """第k要素の値を出力する.

        k:数列の要素
        index:先頭の要素の番号
        """

        p=k+(1-index)
        return self.sum(p,p,index)

    def add(self,k,x,index=1,right=False):
        """第k要素にxを左から加え,更新を行う.

        k:数列の要素
        x:更新後の値
        index:先頭の要素の番号
        right:「左から」が「右から」になる
        """
        p=k+(1-index)
        while p<=self.num:
            if right==False:
                #左から
                self.data[p]=self.calc(x,self.data[p])
            else:
                #右から
                self.data[p]=self.calc(self.data[p],x)
            p+=p&(-p)

    def update(self,k,x,index=1,right=False):
        """第k要素をxに変え,更新を行う.

        k:数列の要素
        x:更新後の値
        """

        a=self.index(k,index)
        if right==False:
            #左から
            y=self.calc(x,self.inv(a))
        else:
            #右から
            y=self.calc(self.inv(a),x)

        self.add(k,y,index,right)

    def sum(self,From,To,index=1):
        """第From要素から第To要素までの総和を求める.

        ※From!=1を使うならば,群でなくてはならない.
        From:始まり
        To:終わり
        index:先頭の要素の番号
        """
        alpha=max(1,From+(1-index))
        beta=min(self.num,To+(1-index))

        if alpha==1:
            return self.__section(beta)
        else:
            return self.calc(self.inv(self.__section(alpha-1)),self.__section(beta))

    def __section(self,To):
        S=self.unit
        x=To
        while x>0:
            S=self.calc(self.data[x],S)
            x-=x&(-x)
        return S

    def all_sum(self):
        return self.data[-1]

    def __getitem__(self,index):
        if isinstance(index,int):
            return self.sum(index,index,self.index)
        else:
            return [self.sum(t,t,self.index) for t in index]
#================================================
import sys
from operator import add,neg
input=sys.stdin.readline
N=int(input())
B=Binary_Indexed_Tree([0]*N,add,0,neg,1)
X=0
for i in range(N):
    m=int(input())
    B.add(m,1,1)
    X+=B.sum(m+1,N,1)
print(X)
0