【bzoj4994】[Usaco2017 Feb]Why Did the Cow Cross the Road III 树状数组
题目描述
给定长度为2N的序列,1~N各处现过2次,i第一次出现位置记为ai,第二次记为bi,求满足ai<aj<bi<bj的对数
样例输入
4
3
2
4
4
1
3
2
1
样例输出
3
题解
树状数组
WH说是CDQ分治直接把我整蒙了。。。
把所有数按照第一次出现位置从小到大排序,然后扫一遍。此时一定是满足$a_j>a_i$的。
那么只需要求出$(a_j,b_j)$中以前出现过的$b_i$的数目。使用树状数组维护即可。
时间复杂度$O(n\log n)$
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 50010
using namespace std;
struct data
{
int a , b;
bool operator<(const data &x)const {return a < x.a;}
}v[N];
int n , f[N << 1];
inline void add(int x)
{
int i;
for(i = x ; i <= n << 1 ; i += i & -i) f[i] ++ ;
}
inline int query(int x)
{
int i , ans = 0;
for(i = x ; i ; i -= i & -i) ans += f[i];
return ans;
}
int main()
{
int i , x , ans = 0;
scanf("%d" , &n);
for(i = 1 ; i <= n << 1 ; i ++ )
{
scanf("%d" , &x);
if(!v[x].a) v[x].a = i;
else v[x].b = i;
}
sort(v + 1 , v + n + 1);
for(i = 1 ; i <= n ; i ++ ) ans += query(v[i].b - 1) - query(v[i].a - 1) , add(v[i].b);
printf("%d\n" , ans);
return 0;
}
浙公网安备 33010602011771号