分析
首先这道题是可以用的时间复杂度过的
所以我们可以考虑使用数据结构优化一下
所以我们选择可以直接获得区间信息的树状数组
将所有区间按排序之后,依次遍历
将前一个出现当前颜色的
将当前位置即可
统计区间答案
代码
//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;
} 
京公网安备 11010502036488号