记录下第一次出现的位置和 两次出现位置的距离差,按照距离差降序排个序,然后扫一遍。。
我看网上别人做法扫一遍,再扫一遍,完事了,效率比我这要高。。。没想到
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
struct node
{
int si,dis;
};
const int MAXN = 200020;
node ns[MAXN/2];
int cnt[MAXN];
int N,num;
bool cmp(const node& a, const node& b)
{
return a.dis > b.dis;
}
int lowBit(int x)
{
return x&-x;
}
int sum(int i)
{
int s = 0;
while(i > 0)
{
s += cnt[i];
i -= lowBit(i);
}
return s;
}
void add(int i, int x)
{
while(i <= N*2)
{
cnt[i] += x;
i += lowBit(i);
}
}
int main()
{
while(scanf("%d",&N) != EOF)
{
memset(cnt,0,sizeof(cnt));
memset(ns,0,sizeof(ns));
for(int i = 1; i <= 2*N; ++i)
{
add(i,1);
scanf("%d",&num);
//记录每个数字第一次出现的下标和两个下标之间的差
if(ns[num].si == 0)
ns[num].si = i;
else
ns[num].dis = i-ns[num].si;
}
sort(ns+1,ns+1+N,cmp);
int res = 0;
for(int i = 1; i <= N; ++i)
{
res += sum(ns[i].si+ns[i].dis)-sum(ns[i].si);
add(ns[i].si,-1);
add(ns[i].si+ns[i].dis,-1);
}
printf("%d\n",res);
}
return 0;
}