赞
踩
题意
给出一个序列,求有几个子段和 s u m sum sum 满足 L ≤ s u m ≤ R L \le sum \le R L≤sum≤R
题解
设 p r e n = ∑ i = 1 n a i pre_n=\sum_{i=1}^{n}a_i pren=∑i=1nai,则需找到点对 ( i , j ) (i,j) (i,j)使:
类似一个三维偏序,同时关注到第二维和第三维都是 pre 的比较,所以可以用尺取来代替数据结构维护
#include<iostream> #include<sstream> #include<string> #include<queue> #include<map> #include<unordered_map> #include<set> #include<vector> #include<stack> #include <utility> #include<list> #include<bitset> #include<algorithm> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<iomanip> #include<time.h> #include<random> using namespace std; #include<ext/pb_ds/priority_queue.hpp> #include<ext/pb_ds/tree_policy.hpp> #include<ext/pb_ds/assoc_container.hpp> #include<ext/pb_ds/hash_policy.hpp> using namespace __gnu_pbds; #include<ext/rope> using namespace __gnu_cxx; #define int long long #define PI acos(-1.0) #define eps 1e-9 #define lowbit(a) ((a)&-(a)) #define mid ((l+r)>>1) #define mem(x,y) memset(x,y,sizeof x) const int mod = 1e9+7; int qpow(int a,int b){ int ans=1; while(b){ if(b&1)ans=(ans*a)%mod; a=(a*a)%mod; b>>=1; } return ans; } const int INF = 0x3f3f3f3f; const int N = 1e6+10; int a[N],pre[N],n,L,R,ans; void cdq(int l,int r){ if(l==r)return; cdq(l,mid),cdq(mid+1,r); sort(pre+l,pre+mid+1),sort(pre+mid+1,pre+r+1); int u=l,v=l-1; for(int i=mid+1;i<=r;i++){ while(v+1<=mid&&pre[i]-pre[v+1]>=L)v++; while(u<=v&&pre[i]-pre[u]>R)u++; ans+=v-u+1; } } #define endl '\n' signed main(){ std::ios::sync_with_stdio(false); cin.tie(0),cout.tie(0); cin>>n>>L>>R; for(int i=1;i<=n;i++)cin>>a[i],pre[i]=pre[i-1]+a[i]; cdq(0,n); cout<<ans<<endl; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。