[BZOJ 1106] [POI2007] 立方体大作战tet 【树状数组】
题目链接:BZOJ - 1106
题目分析
从1到2n枚举每一个位置。
如果枚举到某一个数,这个数已经是第二次出现,那么就看它和第一次出现的位置之间有多少数还没有被匹配,有多少没有匹配的就要进行多少次交换。
代码
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
const int MaxN = 100000 + 5;
int n, Ans;
int A[MaxN], T[MaxN], L[MaxN];
void Add(int x, int Num)
{
for (int i = x; i <= n; i += i & -i)
T[i] += Num;
}
int Get(int x)
{
int ret = 0;
for (int i = x; i; i -= i & -i)
ret += T[i];
return ret;
}
int main()
{
scanf("%d", &n);
n <<= 1;
for (int i = 1; i <= n; ++i) scanf("%d", &A[i]);
Ans = 0;
for (int i = 1; i <= n; ++i)
{
if (L[A[i]] == 0)
{
L[A[i]] = i;
Add(i, 1);
}
else
{
Ans += Get(i) - Get(L[A[i]]);
Add(L[A[i]], -1);
}
}
printf("%d\n", Ans);
return 0;
}

浙公网安备 33010602011771号