标签:mes query 描述 scan 整数 子序列 algorithm 树状 +=
题目描述
输入
输出
样例输入
5 5 9
1 2 3 4 5
样例输出
6
题解
离散化+树状数组
把序列和转化为前缀相减,即选出满足$L\le sum[x]-sum[y]\le R$的$x>y$的数对个数。
那么我们枚举$x$,即可得到$y$的范围,要求的是以前的满足条件的$y$的个数。可以维护1到当前位置树状数组,在树状数组中查询个数,最后再把该数加入到树状数组中。由于数据范围大,因此需要离散化。
时间复杂度$O(n\log n)$
#include <cstdio> #include <algorithm> #define N 100010 #define now v + 1 , v + n + 2 using namespace std; typedef long long ll; ll sum[N] , v[N]; int f[N] , n; 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; ll l , r , ans = 0; scanf("%d%lld%lld" , &n , &l , &r); for(i = 1 ; i <= n ; i ++ ) scanf("%lld" , &sum[i]) , sum[i] += sum[i - 1] , v[i] = sum[i]; sort(now); for(i = 0 ; i <= n ; i ++ ) ans += query(upper_bound(now , sum[i] - l) - v - 1) - query(lower_bound(now , sum[i] - r) - v - 1) , add(lower_bound(now , sum[i]) - v); printf("%lld\n" , ans); return 0; }
【bzoj4627】[BeiJing2016]回转寿司 离散化+树状数组
标签:mes query 描述 scan 整数 子序列 algorithm 树状 +=
原文地址:http://www.cnblogs.com/GXZlegend/p/7662744.html