結果
問題 | No.2089 置換の符号 |
ユーザー |
👑 ![]() |
提出日時 | 2022-09-30 21:27:55 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 58 ms / 2,000 ms |
コード長 | 3,506 bytes |
コンパイル時間 | 602 ms |
コンパイル使用メモリ | 82,432 KB |
実行使用メモリ | 64,896 KB |
最終ジャッジ日時 | 2024-12-22 22:19:34 |
合計ジャッジ時間 | 2,914 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 33 |
ソースコード
class Permutation():def __init__(self, n, p=[]):if p==[]:self.p=[i for i in range(n)]self.ind=[i for i in range(n)]else:self.p=pself.ind=[0]*nfor i in range(n):self.ind[p[i]]=iself.n=ndef __getitem__(self, k):return self.p[k]def __str__(self):return str(self.p)__repr__=__str__def __eq__(self,other):return (self.n==other.n) and (self.p==other.p)def __mul__(self,other):assert self.n==other.np=self.p; q=other.preturn Permutation(self.n, [p[q[i]] for i in range(self.n)])def __pow__(self, n):if n<0:return pow(self,-n).inverse()a=list(range(self.n))e=self.p[:]while n:if n&1:a=[a[e[i]] for i in range(self.n)]e=[e[e[i]] for i in range(self.n)]n>>=1return Permutation(self.n, a)def __truediv__(self,other):passdef sgn(self):""" 置換の符号を求める (偶置換 → 1, 奇置換 → -1)"""return -1 if self.minimum_transposition()%2 else 1def inverse(self):return Permutation(self.n, self.ind)def inversion(self):""" 転倒数を求める."""BIT=[0]*(self.n+1)Y=(self.n*(self.n-1))//2for a in self.p:s=awhile 1<=s:Y-=BIT[s]s-=s&(-s)r=a+1while r<=self.n:BIT[r]+=1r+=r&(-r)return Ydef swap(self, i, j):""" i 番目と j 番目を交換する ※ i と j を交換ではない"""u=self.p[i]; v=self.p[j]self.p[i]=v; self.p[j]=uself.ind[v]=i; self.ind[u]=jdef transposition(self, u, v):""" u と v を交換する ※ u 番目とv 番目ではない"""a=self.ind[u]; b=self.ind[v]self.p[a]=v; self.p[b]=uself.ind[u]=b; self.ind[v]=adef minimum_transposition(self):""" 互換の最小回数を求める. """return self.n-len(self.cycle_division())def cycle_division(self, mode=True):""" 置換を巡回置換の積に分解する.mode: 自己ループを入れるか否か"""p=self.pT=[False]*self.nA=[]for k in range(self.n):if not T[k]:a=[k]T[k]=Truev=p[k]while v!=k:T[v]=Truea.append(v)v=p[v]if mode or len(a)>=2:A.append(a)return Adef operate_list(self, list):assert self.n==len(list),"置換の長さとリストの長さが違います."return [list[self.ind[i]] for i in range(self.n)]def order(self, mod=None):""" 位数を求める (mod を指定すると, mod で割った余りになる)."""from math import gcdx=1for m in self.cycle_division():g=gcd(x,len(m))x=(x//g)*len(m)return x#==================================================def solve():N=int(input())A=list(map(int,input().split()))for i in range(N):A[i]-=1P=Permutation(N,A)inv=P.inversion()return 1 if inv%2==0 else -1print(solve())