Official

E - Make it Palindrome Editorial by en_translator


First, let us find how to evaluate \(f(B)\) for some consecutive subarray \(B\).

Let \(A=(2,4,4,9,4,8,9,7,4)\), then

  • for a subarray \((2,4,4,9)\) consisting of \([1,4]\)-th elements,

    • the \(1\)-st and \(4\)-th elements are different, so one of them must be changed;
    • the \(2\)-nd and \(3\)-rd elements are the same, so there is no need to change.
  • Thus, \(f(2,4,4,9)=1\).

  • For a subarray \((4,8,9,7,4)\) consisting of \([5, 9]\)-th elements,

    • the \(5\)-th and \(9\)-th elements are the same, so there is no need to change;
    • the \(6\)-th and \(8\)-th elements are different, so one of them must be changed.
  • Thus, \(f(4,8,9,7,4)=1\).

Imagine connecting with a line the elements that must be equal to make it a palindrome, as in the figure below.

  • If two connected elements are equal, the answer does not change. We say such a line is good.
  • If two connected elements are different, the answer increases. We say such a line is bad.
  • We collective call these lines, simply, “lines.”

All we need is to count the number of bad lines over all consecutive subarrays.
Here, we can say that (number of bad lines) = (total number of lines) - (number of good lines).
Instead of counting bad lines, which seems a bit difficult, let us evaluate the right hand side.

First, how many lines are there in total? It can be expressed as follows: \(\displaystyle \sum_{i=1}^{N} \left ( (N+1-i) \times \left \lfloor \frac{i}{2} \right \rfloor \right )\), where \(\lfloor x \rfloor\) is a function, i.e. the integer obtained by dropping the fractional part of \(x\).
You may apply a clever deformation to evaluate in an \(O(1)\) time, or just evaluating naively in an \(O(N)\) time. Only fast implementation matters during the contest.

Now how can we count the total number of bad lines?
Let us apply a common combinatoric trick: counting how many times each element is counted. (This trick is called “preposterous trick” in Japan.)
Specifically, instead of counting how many good lines each subarray yields, we count how many subarrays yields each of the possible good lines.
For example, when \(A=(2,4,4,9,4,8,9,7,4)\), the line connecting the \(3\)-rd and \(5\)-th elements is counted for subarrays \([1,7],[2,6]\) and \([3,5]\). (See the figure below)

In general, the good line connecting the \(l\)-th and \(r\)-th elements is counted for \(\min(l,N+1-r)\) subarrays.
Ultimately, the problem is boiled down as follows:

  • For an integer \(x\), let \(P\) be the positions of \(x\), in ascending order. (For example, if \(A=(2,4,4,9,4,8,9,7,4)\) and \(x=4\), then \(P=(2,3,5,9)\).)
  • The sought value is the sum of \(\displaystyle \sum_{i=1}^{|P|-1} \sum_{j=i+1}^{|P|} \min(P_i,N+1-P_j)\) over all \(x\).

This problem can be solved in the following procedure.

  • Initially, let \(l=1\) and \(r=|P|\).
  • Repeat the following steps while \(l<r\).
    • If \(P_l < N+1-P_r\), then \(P_x < N+1-P_y\) for all \((x,y)=(l,l+1),(l,l+2),\dots,(l,r)\), so add \((r-l) \times P_l\) to the answer, and let \(l=l+1\).
    • Otherwise, \(P_x \ge N+1-P_y\) for all \((x,y)=(l,r),(l+1,r),\dots,(r-1,r)\), so add \((r-l) \times (N+1-P_r)\) to the answer, and let \(r=r-1\).

Now that we also found the total number of good lines, the problem has been solved.
By constructing \(P\) (for all \(x\)) while receiving the input in the manner of packet sort, it can be implemented in a total time complexity of \(O(N)\).

Sample code (C++):

#include<bits/stdc++.h>

using namespace std;

int main(){
  long long n;
  cin >> n;
  vector<vector<long long>> p(n+1);
  for(int i=1;i<=n;i++){
    long long x;
    cin >> x;
    p[x].push_back(i);
  }
  long long res=0;
  for(long long i=1;i<=n;i++){
    res+=(n+1-i)*(i/2);
  }
  for(long long i=1;i<=n;i++){
    long long l=0,r=p[i].size()-1;
    while(l<r){
      if(p[i][l]<(n+1-p[i][r])){
        res-=(r-l)*p[i][l];
        l++;
      }
      else{
        res-=(r-l)*(n+1-p[i][r]);
        r--;
      }
    }
  }
  cout << res << "\n";
  return 0;
}

posted:
last update: