Problem Müəllifi: | Hasan Saleh (MathModel) |
Hazırlayan: | Hasan Saleh (MathModel) |
Redaktə edən: | Hasan Saleh (MathModel) |
Həll
Biz yalnız hansı indeksləri saxlayırıq (0 əməliyyat) və hansını bir anda düzəldirik (1 əməliyyat) ilə maraqlanırıq. a_i üzərində bir əməliyyat a_i\leftarrow(a_i+t)\bmod k ilə t\ge m icazə verir, və biz -nın istənilən katını əlavə edə bildiyimiz üçün, bir əməliyyat a_i-ni [0,k-1] aralığında istənilən dəyərə təyin edə bilər. Beləliklə:
saxlanılan indeks: dəyər a_i olaraq qalır,
dəyişdirilən indeks: dəyər [0,k-1] aralığında istənilən dəyərə çevrilir.
Vacib məhdudiyyət:
Əgər biz a_i\ge k olan bəzi indeksləri saxlayırıqsa, o zaman onun sağındakı hər şey də saxlanmalı və artıq azalmamalıdır; əks halda, dəyişdirilmiş bir dəyər (\le k-1) -dan sonra yerləşməli olacaq ki, bu da sıralamanı pozar. Beləliklə, a_i\ge k olan bir indeks yalnız ardıcıllığı artıq azalmırsa saxlanmağa uyğun hesab olunur.
Əgər a_i<k-dirsə, həmişə saxlanmağa uyğun hesab olunur (dəyişdirilmiş qonşular [0,k-1] aralığında seçilə bilər).
Biz saxlanılan indekslərin sayını maksimuma çatdırmaq istəyirik; qalanları dəyişdirilir. Hər hansı saxlanılan dəst dəyər baxımından azalmamalıdır. Buna görə də, biz uyğun mövqelər üzərində LIS (azalmayan variant, yəni, -versiyası) götürürük:
burada -də azalmaları sayır. Cavab:
Niyə: saxlanılan elementlər azalmayan alt ardıcıllığı təşkil edir (biz onları heç vaxt dəyişmirik), və hər hansı digər yeri [0,k-1] aralığında dəyişdirilmiş dəyərlərlə doldurmaq mümkündür ki, sıralama saxlanılsın. Əgər saxlanılan görünürsə, uyğunluq onun arxasında dəyişdirilmiş girişlərin olmadığı təmiz azalmayan ardıcıllığı təmin edir.
Hesablama mürəkkəbliyi \mathcal{O}(n \log n)-dir.
def solve():
n,m,k=map(int,input().split())
a=list(map(int,input().split()))
suf=[0]*n
for i in range(n-2,-1,-1):
suf[i]=suf[i+1]+(a[i]>a[i+1])
INF=10**18
dp=[INF]*(n+1)
dp[0]=-INF
lis=0
for i in range(n):
if a[i]<k or suf[i]==0:
l,r,b=1,n,0
while l<=r:
mid=(l+r)//2
if dp[mid]<=a[i]:
b=mid;l=mid+1
else:
r=mid-1
if a[i]<dp[b+1]: dp[b+1]=a[i]
if b+1>lis: lis=b+1
print(n-lis)
for _ in range(int(input())):
solve()