Yaxın Döyüş#12255

Yaxın Döyüş (Həll təhlili)

Problem Müəllifi:

Tamzid Alahi (Tamzid1) və Hasan Saleh (MathModel)

Hazırlayan:

Hasan Saleh (MathModel)

Redaktə edən:

Hasan Saleh (MathModel)

Həll

Hər bir indeks üçün sinif açarını müəyyən edin

K_i=\operatorname{lcm}\big(i,\ \varphi(a_i)\big).

Biz K_i=K_j olan cütlərinin sayını maksimuma çatdırmaq istəyirik, eyni zamanda bir dəfə əməliyyat a_x\leftarrow a_x+1 tətbiq etməyə icazə verilir.

1) Əsas xətt (əməliyyatsız). dəyəri olan \{K_i\} arasında tezliyi olsun. Etibarlı cütlərin sayı

\text{pairs}_0=\sum_v \binom{\text{cnt}[v]}{2}.

2) -də bir artırma cəhd edin. Əgər a_i-ni artırsaq, onun açarı

K_i'=\operatorname{lcm}\big(i,\ \varphi(a_i+1)\big),

bütün digər K_j eyni qalır. İndeks -nin cütlərə töhfəsi \text{cnt}[K_i]-1-dən

\text{cnt}'[K_i']= \begin{cases} \text{cnt}[K_i'] & \text{əgər } K_i'\ne K_i,\\ \text{cnt}[K_i]-1 & \text{əgər } K_i'=K_i, \end{cases}

şəklində dəyişir, çünki biz konseptual olaraq əvvəlcə -ni \text{cnt}[K_i]-dən çıxarırıq, sonra isə onu K_i' sinfinə əlavə edirik. Beləliklə, yeni cəmi

\text{pairs}_i=\text{pairs}_0-\big(\text{cnt}[K_i]-1\big)+\big(\text{cnt}[K_i']-\mathbf{1}_{K_i'=K_i}\big).

Sadəcə olaraq

\max\big(\text{pairs}_0,\ \max_i \text{pairs}_i\big)

alırıq.

Məhdudiyyətlər a_i\le 10^5 verir, buna görə də a_i+1\le 10^5+1. -i 1\le x\le 100001 üçün bir dəfə xətti/başqa bir üsul ilə əvvəlcədən hesablayın.

Komplekslik \mathcal{O}(10^5 \log \log 10^5+\sum n)

import math

M=100001
phi=list(range(M+1))
for p in range(2,M+1):
    if phi[p]==p:
        for x in range(p,M+1,p):
            phi[x]-=phi[x]//p

def lcm(a,b): 
    return a//math.gcd(a,b)*b

for _ in range(int(input())):
    n=int(input())
    a=list(map(int,input().split()))
    K=[lcm(i+1, phi[a[i]]) for i in range(n)]
    from collections import Counter
    cnt=Counter(K)
    base=sum(c*(c-1)//2 for c in cnt.values())
    ans=base
    for i in range(n):
        x=K[i]
        y=lcm(i+1, phi[a[i]+1])
        cx=cnt[x]
        cy=cnt.get(y,0)
        if y==x:
            cur=base 
        else:
            cur=base-(cx-1)+cy
        if cur>ans: ans=cur
    print(ans)