分析

首先这道题是可以用的时间复杂度过的
所以我们可以考虑使用数据结构优化一下
所以我们选择可以直接获得区间信息的树状数组
将所有区间按排序之后,依次遍历
将前一个出现当前颜色的
将当前位置即可统计区间答案

代码

//Newcoder 18 B
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>

#define LL long long
#define Lowbit(X) (X&(-X))
#define Lson (X<<1)
#define Rson (X<<1|1)
#define Cl(X,Y) memset((X),(Y),sizeof(X))
#define FOR(i,A,B) for(LL i=A;i<=B;i++)
#define BOR(i,A,B) for(LL i=A;i>=B;i--)
#define FOR_SIDE(i,A) for(LL i=Head[A];i;i=Next[i])
#define INF 0x3f3f3f3f3f3f3f3f
using namespace std;
const int MAXN = 1e6 + 100;
int Num[MAXN],Temp[MAXN],last[MAXN],Side,Total,So;
struct Node{int l,r,id;}q[MAXN];
inline bool cmp(Node x,Node y) { return x.r < y.r; }
inline void add(int x,int d){ while(x<=Total)  Temp[x] += d,x+=Lowbit(x); }
inline int ask(int x){ int Res = 0; while(x) Res += Temp[x],x-=Lowbit(x); return Res; }
int main()
{
    scanf("%d",&Total);
    FOR(i,1,Total) scanf("%d",&Num[i]);
    Side = 0;
    FOR(i,1,Total) FOR(j,1,Total) 
        q[++Side].l = i,q[Side].r = j,q[Side].id = Side; 
    sort(q+1,q+1+Side,cmp);
    for(int i = 1,R = 0;i <= Side;i++)
    {
        while(R < q[i].r)
        {
            R++;
            if(!last[Num[R]]) last[Num[R]] = R;
            else {
                add(last[Num[R]],-1);
                last[Num[R]] = R;
            } 
            add(R,1);
        }
        So += ask(q[i].r) - ask(q[i].l-1);
    }
    printf("%d\n",So);
    //system("pause");
    return 0;
}