[codeforces] 1921F. Sum of Progression

starbow·2024년 6월 7일

PS/CP

목록 보기
10/25

문제 링크

길이가 nn인 정수 배열 aaqq개의 쿼리가 s,d,ks, d, k 형식으로 주어집니다. 각 쿼리에 대해서 as+2as+d++kas+d(k1)a_{s} + 2 \cdot a_{s+d} + \cdots + k \cdot a_{s + d \cdot (k-1)}을 구하면 됩니다.

nn은 최대 10만, qq는 최대 20만까지 주어지기 때문에 각 쿼리에 대해서 Naive하게 계산하면 TLE를 받습니다. (시간복잡도 O(nq)O(nq)) 시간복잡도를 줄일 수 있는 다른 방법을 생각해봐야 합니다.

잘 생각해보면 dd가 클 수록 더하는 값의 갯수가 줄어들 수 밖에 없다는것을 알 수 있습니다. 즉, dd가 클 때는 그냥 Naive하게 더하고 dd가 작을때는 다른 방식으로 구하는 방향으로 풀이를 생각해 볼 수 있습니다.

그럼 케이스를 나눠서 생각해보겠습니다.

Case 1) dnd \geq \sqrt{n}

이 때는 그냥 Naive하게 더합니다. 항의 갯수가 O(n)O(\sqrt{n})이므로 O(n)O(\sqrt{n})에 값을 구할 수 있습니다.

Case 2) d<nd < \sqrt{n}

a0=0a_{0} = 0으로 설정하면 식을 아래와 같이 변형시킬 수 있습니다.

as+2as+d++kas+d(k1)=a(smodd)+2a(smodd)+d++sdasd+(sd+1)as++(sd+k)as+d(k1)(a(smodd)+2a(smodd)+d++sdasd)sd(as+as+d++as+d(k1))\begin{aligned} &a_{s} + 2 \cdot a_{s+d} + \cdots + k \cdot a_{s + d \cdot (k-1)} \\ = \, &a_{(s \, \mathrm{mod} \, d)} + 2 \cdot a_{(s \, \mathrm{mod} \, d)+d} + \cdots + \left\lfloor{\frac{s}{d}}\right\rfloor \cdot a_{s-d} + \left(\left\lfloor{\frac{s}{d}}\right\rfloor+1 \right) \cdot a_{s} + \cdots + \left(\left\lfloor{\frac{s}{d}}\right\rfloor+k \right) \cdot a_{s + d \cdot (k-1)} \\ &- \left( a_{(s \, \mathrm{mod} \, d)} + 2 \cdot a_{(s \, \mathrm{mod} \, d)+d} + \cdots + \left\lfloor{\frac{s}{d}}\right\rfloor \cdot a_{s-d} \right) \\ &- \left\lfloor{\frac{s}{d}}\right\rfloor \cdot \left( a_{s} + a_{s+d} + \cdots + a_{s + d \cdot (k-1)} \right) \\ \end{aligned}

그리고 As,dA_{s, d}Bs,dB_{s, d}를 아래와 같이 정의 하겠습니다.

As,d=a(smodd)+2a(smodd)+d++sdasd+(sd+1)asBs,d=a(smodd)+a(smodd)+d++asd+as\begin{aligned} &A_{s, d} = a_{(s \, \mathrm{mod} \, d)} + 2 \cdot a_{(s \, \mathrm{mod} \, d)+d} + \cdots + \left\lfloor{\frac{s}{d}}\right\rfloor \cdot a_{s-d} + \left(\left\lfloor{\frac{s}{d}}\right\rfloor+1 \right) \cdot a_{s} \\ &B_{s, d} = a_{(s \, \mathrm{mod} \, d)} + a_{(s \, \mathrm{mod} \, d)+d} + \cdots + a_{s-d} + a_{s} \end{aligned}

그럼 우리가 구해야 하는 식은 아래와 같이 변형됩니다.

as+2as+d++kas+d(k1)=As+d(k1),dAsd,dsd(Bs+d(k1),dBsd,d)\begin{aligned} &a_{s} + 2 \cdot a_{s+d} + \cdots + k \cdot a_{s + d \cdot (k-1)} \\ = \, &A_{s + d \cdot (k-1), d} - A_{s-d, d} - \left\lfloor{\frac{s}{d}}\right\rfloor \cdot \left( B_{s + d \cdot (k-1), d} - B_{s-d, d} \right) \end{aligned}

즉, As,dA_{s, d}Bs,dB_{s, d}만 전치리를 해놓는다면 O(1)O(1)에 값을 구할 수 있습니다.

As,dA_{s, d}Bs,dB_{s, d}의 전처리는 O(nn)O(n\sqrt{n})에 할 수 있습니다. 그래서 전체 시간복잡도는 O((n+q)n)O((n+q)\sqrt{n})이 됩니다.

n\sqrt{n}을 기준으로 케이스를 나눈 이유는 만약에 bb를 기준으로 케이스를 나누면 시간복잡도는 O(nb+qnb)O\left( nb+q \cdot \frac{n}{b} \right)이 됩니다. TLE가 나지 않도록 bb값을 설정하면 되고 저는 그 중에서 n\sqrt{n}을 선택했습니다.

profile
🎈 Journey of problem solving

0개의 댓글