标签: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