序列

源代码:

#include<cstdio>
#include<vector>
#include<algorithm>
#define LL long long
using namespace std;
LL n,m,Ans(0),Sum(0),i[100001];
vector <LL> Q[100001];
int main()
{
    scanf("%I64d%I64d",&n,&m);
    for (LL a=1;a<=m;a++)
      scanf("%I64d",&i[a]);
    for (LL a=1;a<=m;a++)
    {
        if (a>1&&i[a-1]!=i[a])
          Q[i[a-1]].push_back(i[a]); //相邻关系。
        if (a<m&&i[a+1]!=i[a])
          Q[i[a+1]].push_back(i[a]);
    }
    for (LL a=1;a<=n;a++)
    {
        if (!Q[a].size())
          continue;
        sort(Q[a].begin(),Q[a].end());
        LL T=Q[a][Q[a].size()>>1];
        LL T1(0),T2(0);
        for (LL b=0;b<Q[a].size();b++)
        {
            T1+=abs(a-Q[a][b]);
            T2+=abs(T-Q[a][b]);
        }
        Ans=max(Ans,T1-T2);
        Sum+=T1;
    }
    printf("%I64d",(Sum>>1)-Ans); //注意数据类型。
    return 0;
}

/*
    一道很奇怪的题,但也是挺理性的题。
    发现,对答案有影响的是其相邻数,链表存储。
    易得,中位数最优,排序取中位数(偶数对答案贡献相同),取最大贡献即可。
    做题应该从理性的角度出发,分析应该分析的内容,然后思考解法。
    看似时间复杂度较高,其实想想,它有一部分被均分了。
*/
原文地址:https://www.cnblogs.com/Ackermann/p/6058664.html