문제 링크
길이가 n인 정수 배열 a와 q개의 쿼리가 s,d,k 형식으로 주어집니다. 각 쿼리에 대해서 as+2⋅as+d+⋯+k⋅as+d⋅(k−1)을 구하면 됩니다.
n은 최대 10만, q는 최대 20만까지 주어지기 때문에 각 쿼리에 대해서 Naive하게 계산하면 TLE를 받습니다. (시간복잡도 O(nq)) 시간복잡도를 줄일 수 있는 다른 방법을 생각해봐야 합니다.
잘 생각해보면 d가 클 수록 더하는 값의 갯수가 줄어들 수 밖에 없다는것을 알 수 있습니다. 즉, d가 클 때는 그냥 Naive하게 더하고 d가 작을때는 다른 방식으로 구하는 방향으로 풀이를 생각해 볼 수 있습니다.
그럼 케이스를 나눠서 생각해보겠습니다.
Case 1) d≥n
이 때는 그냥 Naive하게 더합니다. 항의 갯수가 O(n)이므로 O(n)에 값을 구할 수 있습니다.
Case 2) d<n
a0=0으로 설정하면 식을 아래와 같이 변형시킬 수 있습니다.
=as+2⋅as+d+⋯+k⋅as+d⋅(k−1)a(smodd)+2⋅a(smodd)+d+⋯+⌊ds⌋⋅as−d+(⌊ds⌋+1)⋅as+⋯+(⌊ds⌋+k)⋅as+d⋅(k−1)−(a(smodd)+2⋅a(smodd)+d+⋯+⌊ds⌋⋅as−d)−⌊ds⌋⋅(as+as+d+⋯+as+d⋅(k−1))
그리고 As,d와 Bs,d를 아래와 같이 정의 하겠습니다.
As,d=a(smodd)+2⋅a(smodd)+d+⋯+⌊ds⌋⋅as−d+(⌊ds⌋+1)⋅asBs,d=a(smodd)+a(smodd)+d+⋯+as−d+as
그럼 우리가 구해야 하는 식은 아래와 같이 변형됩니다.
=as+2⋅as+d+⋯+k⋅as+d⋅(k−1)As+d⋅(k−1),d−As−d,d−⌊ds⌋⋅(Bs+d⋅(k−1),d−Bs−d,d)
즉, As,d와 Bs,d만 전치리를 해놓는다면 O(1)에 값을 구할 수 있습니다.
As,d와 Bs,d의 전처리는 O(nn)에 할 수 있습니다. 그래서 전체 시간복잡도는 O((n+q)n)이 됩니다.
n을 기준으로 케이스를 나눈 이유는 만약에 b를 기준으로 케이스를 나누면 시간복잡도는 O(nb+q⋅bn)이 됩니다. TLE가 나지 않도록 b값을 설정하면 되고 저는 그 중에서 n을 선택했습니다.