Я опаздываю на вечеринку, но у меня есть линейное решение временной сложности.
Для меня это больше математическая проблема.Вы можете прочитать подробное решение в этом блоге , написанном мной.Далее следует краткое описание.Я хотел бы поставить немного LaTeX, но SO не позволяет этого.
Предположим, что для данных n
и k
наш ответ дается функцией f(n,k)
.Используя метод Беггара, мы можем получить следующую формулу
f(n,k) = SUM C(k+a-1,a-1)*C(n-k+1-a,a)
, где a
проходит от 1
до (n-k+1)/2
Здесь C(p,q)
обозначает биномиальные коэффициенты.
Итак, чтобы получить наш ответ, мы должны рассчитать оба биномиальных коэффициента для каждого значения a
.Мы можем вычислить биномиальную таблицу заранее.Этот подход затем даст наш ответ в O(n^2)
, так как мы должны вычислить таблицу.
Мы можем улучшить сложность времени, используя формулу рекурсии C(p,q) = (p * C(p-1,q-1))/q
для вычисления текущего значения биномиальных коэффициентов из их значенийв предыдущем цикле.
Наш финальный код выглядит следующим образом:
long long x=n-k, y=1, p=n-k+1, ans=0;
ans += x*y;
for(int a=2; a<=p/2; a++)
{
x = (x*(p-2*a+1)*(p-2*a+2))/(a*(p-a+1));
y = (y*(k+a-1))/(a-1);
ans += x*y;
}
Вы можете найти полностью принятое решение в моем GitHub репозитории .