公式

D - Pyramid 解説 by en_translator


Let us call the \(s\)-th term of a pyramid sequence of size \(s\) its top.


Initially, we consider the condition in which repeatedly applying the operation makes it a size-\(s\) pyramid sequence with the opt being the \(k\)-th term \(A_k\) of the original sequence \(A\).

Firstly, the operation does not insert a term, so there must be \((s-1)\) terms on its left and right. Formally, \(s\leq k\leq N-s+1\).
Next, an operation can remove only the first or last term at that point, so the resulting pyramid sequence with \((2s-1)\) terms consists of the \((k-s+1)\)-th through \((k+s-1)\)-th term of the initial \(A\). Moreover, the operation does not increase the terms, so \(A_{i}\geq s-\lvert k-i\rvert\) must hold.

Conversely, if these conditions are satisfied, then one can obtain a pyramid sequence by removing the \((k-s)\)-th and preceding terms, and \((k+s)\)-th and succeeding, and decreasing the other terms as much as required. Thus, the necessary and sufficient condition is

  • \(s\leq k\leq N-s+1\) and \(A_{i}\geq s-\lvert k-i\rvert\) \((k-s+1\leq i\leq k+s-1)\).

Here, any \(i\) with \(1\leq i\leq k-s\) or \(k+s\leq i\leq n\) satisfies \(s-\lvert k-i\rvert\leq 0<A_i\), so it is equivalent to

  • \(s\leq k\leq N-s+1\) and \(A_{i}\geq s-\lvert k-i\rvert\) \((1\leq i\leq N)\).

Furthermore, if we let \(A_0=A_{N+1}=0\), then \(s\leq k\Leftrightarrow A_0\geq s-\lvert k-0\rvert\), and similarly \(k\leq N-s+1 \Leftrightarrow A_{N+1}\geq s-\lvert k-(N+1)\rvert\), so the condition is rewritten to

  • \(A_{i}\geq s-\lvert k-i\rvert\) \((0\leq i\leq N+1)\).


Then, we consider \(s_M(k)\), the maximum \(s\) such that a size-\(s\) pyramid with the top being \(A_k\) can be constructed. Since the condition above is equivalent to \(A_i+\lvert k-i\rvert\geq s\) \((0\leq i\leq N+1)\), it can be found as

\[ s_M(k)=\min_{0\leq i\leq N+1} (A_i+\lvert k-i\rvert). \]

The answer is the maximum \(s_M(k)\) over \(1\leq k\leq N\), so it is sufficient to evaluate \(s_M(k)\) for all \(k=1,2,\ldots,N\).

However, trying to find this value naively costs a total of \(O(N^2)\) time, which is too costly for the constraints this time. So we try to further deform the expression.
Removing the absolute value sign, we have

\[ \begin{aligned} s_M(k) &=\min\left(\min_{0\leq i\leq k} (A_i+k-i), \min_{k+1\leq i\leq N+1} (A_i+i-k) \right) \\ &= \min\left(\min_{0\leq i\leq k} (A_i-i) +k, \min_{k+1\leq i\leq N+1} (A_i+i) -k\right). \end{aligned} \]

Thus, for \(i=1,2,\ldots,N\), it is sufficient to find \(m_1(k)=\displaystyle\min_{0\leq i\leq k} (A_i-i)\) and \(m_2(k)=\displaystyle\min_{k+1\leq i\leq N+1} (A_i+i)\).

\(m_1(k)\) can be found in a total of \(O(N)\) time using the following recurrence relation: \(m_1(1)=\min(A_0,A_1-1)\), \(m_1(k)=\min\left(m_1(k-1),A_k-k\right)\) \((2\leq k\leq N)\).
Likewise, \(m_2(k)\) can also be evaluated by \(m_2(N)=A_{N+1}+(N+1)\), \(m_2(k)=\min\left(m_2(k+1),A_{k+1}+k+1\right)\) \((1\leq k\leq N-1)\).

All that left is to find the answer as \(\displaystyle\max_{1\leq k\leq N} \left\{\min(m_1(k)+k,m_2(k)-k)\right\}\).
The time complexity using this method is \(O(N)\), which is fast enough.
Therefore, the problem has been solved.

Sample code in C++

#include <bits/stdc++.h>
using namespace std;

int main(void){
	int n,ans=0;
	cin>>n;
	vector<int>a(n+2);
	vector<int>m1(n);
	vector<int>m2(n);
	for(int i=0;i<n;i++)cin>>a[i+1];

	m1[0]=min(a[0],a[1]-1);
	for(int i=1;i<n;i++)m1[i]=min(m1[i-1],a[i+1]-i-1);
	m2[n-1]=a[n+1]+n+1;
	for(int i=n-2;i>=0;i--)m2[i]=min(m2[i+1],a[i+2]+i+2);
	for(int i=0;i<n;i++)ans=max(ans,min(m1[i]+i+1,m2[i]-i-1));
	
	cout<<ans<<endl;
	return 0;
}

投稿日時:
最終更新: