結果

問題 No.2873 Kendall's Tau
ユーザー 👑 p-adicp-adic
提出日時 2024-09-06 22:20:41
言語 PyPy3
(7.3.15)
結果
AC  
実行時間 1,441 ms / 4,500 ms
コード長 6,365 bytes
コンパイル時間 190 ms
コンパイル使用メモリ 82,488 KB
実行使用メモリ 271,004 KB
最終ジャッジ日時 2024-09-06 22:21:13
合計ジャッジ時間 23,436 ms
ジャッジサーバーID
(参考情報)
judge5 / judge4
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 40 ms
55,020 KB
testcase_01 AC 36 ms
56,160 KB
testcase_02 AC 37 ms
55,032 KB
testcase_03 AC 36 ms
55,488 KB
testcase_04 AC 36 ms
55,536 KB
testcase_05 AC 36 ms
55,340 KB
testcase_06 AC 36 ms
55,660 KB
testcase_07 AC 1,344 ms
259,360 KB
testcase_08 AC 1,441 ms
261,188 KB
testcase_09 AC 1,278 ms
260,012 KB
testcase_10 AC 1,433 ms
271,004 KB
testcase_11 AC 1,315 ms
259,984 KB
testcase_12 AC 1,414 ms
260,252 KB
testcase_13 AC 421 ms
128,280 KB
testcase_14 AC 1,121 ms
259,528 KB
testcase_15 AC 301 ms
128,260 KB
testcase_16 AC 291 ms
121,944 KB
testcase_17 AC 987 ms
260,528 KB
testcase_18 AC 844 ms
187,356 KB
testcase_19 AC 978 ms
242,356 KB
testcase_20 AC 300 ms
127,076 KB
testcase_21 AC 838 ms
241,772 KB
testcase_22 AC 400 ms
155,680 KB
testcase_23 AC 861 ms
239,748 KB
testcase_24 AC 197 ms
90,600 KB
testcase_25 AC 285 ms
119,536 KB
testcase_26 AC 978 ms
261,832 KB
testcase_27 AC 668 ms
199,976 KB
testcase_28 AC 1,166 ms
259,552 KB
testcase_29 AC 1,249 ms
261,884 KB
testcase_30 AC 267 ms
113,912 KB
testcase_31 AC 382 ms
135,032 KB
testcase_32 AC 806 ms
231,076 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

def rec_str(a):return"".join(["[",", ".join(rec_str(x)for x in a),"]"])if isinstance(a,list)else str(a)
class BIT:
	def __init__(self,x):
		if isinstance(x,int):
			self.N=x
			self.F=[0]*(x+1)
		else:
			self.N=len(x)
			self.F=[0]*(self.N+1)
			for j in R(1,self.N+1):
				i=j-1
				self.F[j]=x[i]
				k=j-(j&-j)
				while i>k:
					self.F[j]+=self.F[i]
					i-=i&-i
	def copy(self):
		a=__class__([])
		a.N=self.N
		a.F=self.F[:]
		return a
	def Add(self,i,u):
		i+=1
		while i<=self.N:
			self.F[i]+=u
			i+=i&-i
	def Set(self,i,u):self.Add(i,u-self.Get(i))
	def Get(self,i):return self.IntervalSum(i,i)
	def InitialSegmentSum(self,r):
		assert(r>-2)
		a=0
		i=min(r+1,self.N)
		while i:
			a+=self.F[i]
			i-=i&-i
		return a
	def IntervalSum(self,l,r):return self.InitialSegmentSum(r)-self.InitialSegmentSum(l-1)
	def list(self):return[self.Get(i)for i in R(self.N)]
	def __str__(self):return rec_str(self.list())
	def Search(self,u):#Computing minimum of j such that InitialSegmentSum(j)>=u or j==N
		j=s=n=0
		p=1<<17 #131072
		while p:
			k=j|p
			p>>=1
			if k<=self.N:
				n+=self.F[k]
				if n<u:s,j=n,k
				else:n=s
		return j

class NonNegativeLineSubset:
	def __init__(self,ubound):
		assert(-1<=ubound)
		self.ubound=ubound
		self.bit=BIT(ubound+1)
	def copy(self):
		a=__class__([])
		a.ubound=self.ubound
		a.bit=self.bit.copy()
		return a
	def insert(self,i):assert(0<=i<=self.ubound);self.bit.Set(i,1)
	def erase(self,i):self.bit.Set(i,0)
	def count(self,i):return self.bit.Get(i)if 0<=i<=self.ubound else 0
	def find(self,i):return self.count(i)>0
	def InitialSegmentSize(self,i_final):return self.bit.InitialSegmentSum(i_final)
	def IntervalSize(self,i_start,i_final):return self.bit.IntervalSum(i_start,i_final)
	def empty(self):return self.InitialSegmentSize(self.ubound)<1
	def MaximumLeq(self,i,k=0):#Returning -1 if not exists
		num=self.InitialSegmentSize(i)-k
		def f(sum,j):return i<=j or num<=sum
		a=self.Search(f)
		return a if num>=0 and self.find(a)else -1
	def MaximumLt(self,i,k=0):return self.MaximumLeq(i-1,k)
	def MinimumGeq(self,i,k=0):return self.MinimumGt(i-1,k)
	def MinimumGt(self,i,k=0):#Returning ubound+1 if not exists
		num=self.InitialSegmentSize(i)+k
		def f(sum,j):return i<j and num<sum
		return self.Search(f)
	def Maximum(self,k=0):return self.MaximumLeq(self.ubound,k)
	def Minimum(self,k=0):return self.MinimumGeq(0,k)
	def RightEndPointOf(self,i,b=False):
		if not b and not self.find(i):return i-1
		c=i-self.InitialSegmentSize(i)
		def f(sum,j):return i<=j and sum+c<j
		return self.Search(f)-1
	def LeftEndPointOf(self,i,b=False):
		if not b and not self.find(i):return i+1
		c=i-self.InitialSegmentSize(i)
		def f(sum,j):return i<=j or (self.find(j)and sum+c==j)
		return self.Search(f)
	def ConnectedComponentOf(self,i,b=False):
		if not b:b=self.find(i)
		return[self.LeftEndPointOf(i,b),self.RightEndPointOf(i,b)]
	def GetConnectedComponent(self):
		a=[]
		l=self.Minimum()
		while l<=self.ubound:
			r=self.RightEndPointOf(l,True)
			a+=[[l,r]]
			l=self.MinimumGt(r)
		return a
	def __str__(self):return rec_str(self.GetConnectedComponent())
	def ubound(self):return self.ubound

	#private:
	def Search(self,f):#Computing minimum of j satisfying f(InitialSegmentSum(j),j) or j==bit.N
		j=s=n=0
		p=1<<17 #131072
		while p:
			k=j|p
			p>>=1
			if k<=self.bit.N:
				n+=self.bit.F[k]
				if f(n,k-1):n=s
				else:s,j=n,k
		return j

class CompressedLineSubset:
	def __init__(self,X):
		self.sorted_list=sorted(set(X))
		N=len(self.sorted_list)
		self.compressed_coordinate={self.sorted_list[i]:i for i in R(N)}
		self.nnls=NonNegativeLineSubset(N-1)
	def copy(self):
		a=__class__([])
		a.sorted_list=self.sorted_list[:]
		a.compressed_coordinate=self.copy()
		a.nnls=self.nnls.copy()
		return a
	def insert(self,i):self.nnls.insert(self.compressed_coordinate[i])
	def erase(self,i):self.nnls.erase(self.compressed_coordinate[i])
	def count(self,i):return self.nnls.count(self.compressed_coordinate[i])if i in self.compressed_coordinate else 0
	def find(self,i):return self.count(i)>0
	def InitialSegmentSize(self,i_final):return self.nnls.InitialSegmentSize(self.compressed_coordinate[i_final])
	def IntervalSize(self,i_start,i_final):return self.nnls.IntervalSize(self.compressed_coordinate[i_start],self.compressed_coordinate[i_final])
	def empty(self):return self.InitialSegmentSize(self.nnls.bit.N-1)<1
	def MaximumLeq(self,i,k=0):
		t=self.nnls.MaximumLeq(self.compressed_coordinate[i],k)
		return self.sorted_list[t]if t>=0 else None
	def MaximumLt(self,i,k=0):
		t=self.nnls.MaximumLt(self.compressed_coordinate[i],k)
		return self.sorted_list[t]if t>=0 else None
	def MinimumGeq(self,i,k=0):
		t=self.nnls.MinimumGeq(self.compressed_coordinate[i],k)
		return self.sorted_list[t]if t<self.nnls.bit.N else None
	def MinimumGt(self,i,k=0):
		t=self.nnls.MinimumGt(self.compressed_coordinate[i],k)
		return self.sorted_list[t]if t<self.nnls.bit.N else None
	def Maximum(self,k=0):return self.MaximumLeq(self.sorted_list[-1],k)
	def Minimum(self,k=0):return self.MinimumGeq(self.sorted_list[0],k)
	def RightEndPointOf(self,i,b=False):
		j=self.compressed_coordinate[i]
		t=self.nnls.RightEndPointOf(j,b)
		return self.sorted_list[t]if j<=t else i-1
	def LeftEndPointOf(self,i,b=False):
		j=self.compressed_coordinate[i]
		t=self.nnls.LeftEndPointOf(j,b)
		return self.sorted_list[t]if t<=j else i+1
	def ConnectedComponentOf(self,i,b=False):
		if not b:b=self.find(i)
		return[self.LeftEndPointOf(i,b),self.RightEndPointOf(i,b)]
	def GetConnectedComponent(self):
		a=[]
		l=self.Minimum()
		while l is not None:
			r=self.RightEndPointOf(l,True)
			a+=[[l,r]]
			l=self.MinimumGt(r)
		return a
	def __str__(self):return rec_str(self.GetConnectedComponent())
R=range
J=lambda:map(int,input().split())
N,*_=J()
Dxy={}
Dyx={}
X=set()
Y=set()
for i in R(N):
	x,y=J()
	X.add(x)
	Y.add(y)
	if x in Dxy:Dxy[x]+=[y]
	else:Dxy[x]=[y]
	if y in Dyx:Dyx[y]+=[x]
	else:Dyx[y]=[x]
X=sorted(list(X))
for x in X:Dxy[x].sort()
query=[N*10**9]
i=0
for x in X:
	for y in Dxy[x]:
		query+=[y*N-1,(y+1)*N+1,y*N+i]
		i+=1
cl=CompressedLineSubset(query)
p=q=r=s=0
i=0
for x in X:
	for y in Dxy[x]:
		p+=cl.InitialSegmentSize(y*N-1)
		q+=cl.IntervalSize((y+1)*N+1,N*10**9)
	for y in Dxy[x]:
		cl.insert(y*N+i)
		i+=1
for x in X:
	L=len(Dxy[x])
	r+=(N-L)*L
for y in Y:
	L=len(Dyx[y])
	s+=(N-L)*L
print((p-q)/(r*s)**0.5*2)
0