题目描述
给定长度为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(nlog 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 " , ans); return 0; }