結果
| 問題 | No.3583 二部マッチング最適化 |
| コンテスト | |
| ユーザー |
👑 |
| 提出日時 | 2025-06-26 21:06:54 |
| 言語 | PyPy3 (7.3.17) |
| 結果 |
AC
|
| 実行時間 | 3,865 ms / 6,000 ms |
| コード長 | 3,289 bytes |
| 記録 | |
| コンパイル時間 | 143 ms |
| コンパイル使用メモリ | 85,248 KB |
| 実行使用メモリ | 98,840 KB |
| 最終ジャッジ日時 | 2026-07-03 21:02:09 |
| 合計ジャッジ時間 | 19,430 ms |
|
ジャッジサーバーID (参考情報) |
judge2_0 / judge3_1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 44 |
ソースコード
R=range 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): if i<0:return 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): assert 0<=i<self.N return self.IntervalSum(i,i) def InitialSegmentSum(self,r): assert -2<r<self.N a=0 i=min(r+1,self.N) while i: a+=self.F[i] i-=i&-i return a def IntervalSum(self,l,r): l,r=max(0,l),min(r,self.N-1) return(self.InitialSegmentSum(r)-self.InitialSegmentSum(l-1))if l<=r else 0 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 IntervalAddBIT: def __init__(self,x): if isinstance(x,int): self.N=x self.F=BIT(x+1) self.G=BIT(x+1) else: self.N=len(x); d=[x[i]-(x[i-1]if i else 0)for i in R(self.N)] self.G=BIT(d) d=[(1-i)*d[i]for i in R(self.N)] self.F=BIT(d) def IntervalAdd(self,l,r,u): l,r=max(0,l),min(r,self.N-1) if l>r:return self.F.Add(l,-(l-1)*u) self.F.Add(r+1,r*u) self.G.Add(l,u) self.G.Add(r+1,-u) def Add(self,i,u):self.IntervalAdd(i,i,u) def Set(self,i,u):self.Add(i,u-self.Get(i)) def InitialSegmentSum(self,r): assert -2<r<self.N return self.F.InitialSegmentSum(r)+r*self.G.InitialSegmentSum(r) def IntervalSum(self,l,r): l,r=max(0,l),min(r,self.N-1) return(self.InitialSegmentSum(r)-self.InitialSegmentSum(l-1))if l<=r else 0 def Get(self,i): assert 0<=i<self.N return self.IntervalSum(i,i) def list(self):return[self.Get(i)for i in R(self.N)] def __str__(self):return rec_str(self.list()) J=lambda:list(map(int,input().split())) N,M,L=J() A=J() B=J() I=1<<33 if(M-L+1)>>(L*L//(N-L+1)): C=[[I]*(L+1)for i in R(L+1)] def G(i,j):return C[i][j]if 0<=i<=L and 0<=j<=L else I C[0][0]=0 for(v,b)in sorted([(v,0)for v in A]+[(v,1)for v in B]): D=[c[:]for c in C] if b: for i in R(L+1): for j in R(L+1):D[i][j]=G(i,j-1)-v if i<j else(G(i,j-1)+v if i>j else min(G(i,j),G(i,j-1)+v)) else: for i in R(L+1): for j in R(L+1):D[i][j]=G(i-1,j)+v if i<j else(G(i-1,j)-v if i>j else min(G(i,j),G(i-1,j)+v)) C=D print(G(L,L)) else: C=[IntervalAddBIT([I]*(M-L+1))for i in R(N-L+1)] def G(i,j):return C[i].Get(j)if 0<=i<=N-L and 0<=j<=M-L else I def S(i,j,v): if 0<=i<=N-L and 0<=j<=M-L:C[i].Set(j,v) S(0,0,0) c=d=0 for(v,b)in sorted([(v,0)for v in A]+[(v,1)for v in B]): if b:d+=1 else:c+=1 for i in R(N-L,-1,-1): D=i-c+d if b: l=G(i,D-1) C[i].IntervalAdd(0,D-1,-v) C[i].IntervalAdd(D,M-L,v) S(i,D,min(l,G(i,D))) else: l=G(i-1,D) C[i].IntervalAdd(0,D,v) C[i].IntervalAdd(D+1,M-L,-v) S(i,D,min(l,G(i,D))) print(G(N-L,M-L))