bzoj4994[Usaco2017 Feb]Why Did the Cow Cross the Road III 树状数组
Posted GXZlegend
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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; }
以上是关于bzoj4994[Usaco2017 Feb]Why Did the Cow Cross the Road III 树状数组的主要内容,如果未能解决你的问题,请参考以下文章
[BZOJ4994] [Usaco2017 Feb]Why Did the Cow Cross the Road III(树状数组)
[BZOJ4989] [Usaco2017 Feb]Why Did the Cow Cross the Road(树状数组)
BZOJ4989 [Usaco2017 Feb]Why Did the Cow Cross the Road 树状数组 逆序对
BZOJ 3942: [Usaco2015 Feb]Censoring