CodeForces - 501E Misha and Palindrome Degree

E. Misha and Palindrome Degree
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Misha has an array of n integers indexed by integers from 1 to n. Let's define palindrome degree of array a as the number of such index pairs (l, r)(1 ≤ l ≤ r ≤ n), that the elements from the l-th to the r-th one inclusive can be rearranged in such a way that the whole array will be a palindrome. In other words, pair (l, r) should meet the condition that after some rearranging of numbers on positions from l to r, inclusive (it is allowed not to rearrange the numbers at all), for any 1 ≤ i ≤ n following condition holds: a[i] = a[n - i + 1].

Your task is to find the palindrome degree of Misha's array.

Input

The first line contains integer n (1 ≤ n ≤ 105).

The second line contains n positive integers a[i] (1 ≤ a[i] ≤ n), separated by spaces — the elements of Misha's array.

Output

In a single line print the answer to the problem.

Examples
input
Copy
3
2 2 2
output
Copy
6
input
Copy
6
3 6 5 3 3 5
output
Copy
0
input
Copy
5
5 5 2 5 2
output
Copy
4
Note

In the first sample test any possible pair (l, r) meets the condition.

In the third sample test following pairs (1, 3), (1, 4), (1, 5), (2, 5) meet the condition.

传送门链接

题意:给n个不超过n的数,取其中一段区间进行重新排列,使之成为回文串,求有多少种方案数?

分析:开始想啦很久没思路,然后手推啦几组找到啦一些规律。即首先找到一个最小的区间,重排就能使数组变成回文串。先从两端开始向中间找最大的回文串。然后中间的串是一个第一个字符和最后一个字符不相等的。这个时候,以这个中间的字符串的首尾字符开始寻找最小的重排区间。然后就能用计数乘法法则得到答案。对于中间的字符串,例如以左边一个字符为最小区间的左边,那么从这个中间字符的最右边开始寻找,具体判断方法见代码。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1e5+5;
int a[N],num[N],na[N],nb[N];
LL ans;
int n,tem;
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=1; i<=n; i++)scanf("%d",&a[i]),num[a[i]]++;
        bool flag=false;
        int val;
        for(int i=1; i<=n; i++)
        {
            if(num[i]%2)
            {
                if(flag)
                {
                    printf("0\n");
                    return 0;
                }
                flag=true;
                val=i;
            }

        }
        int tem=-1;
        for(int i=1,j=n; i<=j; i++,j--)
        {
            if(a[i]!=a[j])
            {
                tem=i;
                break;
            }
            num[a[i]]-=2;
        }
        if(tem==-1)
        {
            printf("%I64d\n",1LL*n*(n+1)/2);
            return 0;
        }
        LL ans=0;
        for(int i=tem;i<=n;i++)
        {
            na[a[i]]++;
            int j=n-i+1;
            if((i<j&&na[a[i]]*2>num[a[i]])||(i==j&&val!=a[i])||(i>j&&a[i]!=a[j]))
            {
                 ans+=(LL)tem*i;break;
            }
        }
        for(int i=n-tem+1;i>=1;i--)
        {
            nb[a[i]]++;
            int j=n-i+1;
            if((i>j&&nb[a[i]]*2>num[a[i]])||(i==j&&val!=a[i])||(i<j&&a[i]!=a[j]))
            {
                ans+=(LL)tem*j;break;
            }
        }
        ans-=(LL)tem*tem;
        printf("%I64d\n",ans);
    }
}


猜你喜欢

转载自blog.csdn.net/m0_37953323/article/details/80017728