Problem Müəllifi: | Hasan Saleh (MathModel) |
Hazırlayan: | Hasan Saleh (MathModel) |
Redaktə edən: | Hasan Saleh (MathModel) |
Həll
Bizə bir permutasiya verilir və bir hərəkətdə i<j<k indeksləri üzərində -lü dövr tətbiq edə bilərik:
Məqsədimiz minimum sayda hərəkət edərək identiklik permutasiyasına çatmaqdır.
Qeyd edin ki, -lü dövr cüt permutasiya olduğundan
Beləliklə, permutasiya pariteti heç vaxt dəyişmir.
Permutasiyanın ayrılmış dövrə (sabit nöqtələr daxil olmaqla) ayrıldığını düşünək. Biz bilirik ki,
Beləliklə, əgər (n-c) təkdirsə, permutasiya təkdir və identikliyin əldə edilməsi mümkün deyil. Bu halda cavab -dir.
İndi (n-c) cütdürsə, fərz edək.
Hər dövrü müstəqil şəkildə işləyə bilərik, buna görə də bir dövrün uzunluğu olan dövrü pozmaq üçün nə qədər əməliyyat lazım olduğunu anlamaq kifayətdir.
Bir -lü dövr əməliyyatı dövrlərin sayını ən çox artırır. Bir uzunluğu olan dövrü sabit nöqtəyə çevirmək üçün dövrlərin sayını (l-1) artırmalıyıq, buna görə də hərəkətlərin sayı ən azı
İndi bu sərhədin əldə oluna biləcəyini göstəririk.
Əgər təkdirsə, dövr özü cütdür. Biz yalnız bu dövrün elementlərindən istifadə edə bilərik və hər əməliyyat dövrlərin sayını artırır. (l-1)/2 hərəkətdən sonra dövr tamamilə sabitləşir.
Əgər cütdürsə, dövr təkdir və tək başına sabitləşdirilə bilmir. Lakin, (n-c) cütdürsə, cüt uzunluqda başqa bir dövr (və ya əlavə elementlər) mövcuddur. Bunu istifadə edərək, dövr hələ də tam olaraq əməliyyatla sabitləşdirilə bilər.
Beləliklə, uzunluğu olan bir dövr dəqiq
hərəkət edir.
Uzunluqları l_1,l_2,\dots,l_c olan bütün dövrləri topladıqda, biz alırıq:
Əgər (n-c) təkdirsə, çıxarın, əks halda yuxarıdakı dəyəri çıxarın.
Mürəkkəblik .
for _ in range(int(input())):
n=int(input())
p=[0]+list(map(int,input().split()))
vis=[0]*(n+1)
ans=0
c=0
for i in range(1,n+1):
if vis[i]: continue
c+=1
cur=i
l=0
while not vis[cur]:
vis[cur]=1
cur=p[cur]
l+=1
ans+=l//2
print(-1 if ((n-c)&1) else ans)