【无旋treap】礼物(2022.5.28)
和洛谷上的P5459 [BJOI2016]回转寿司不能说一模一样,只能说完全相同(这题能评紫?)
题目描述
1.1 题目描述
现在有一排 n 个礼物,每个礼物有一个价格 pi,不过这是一家神奇的商店,店长可能
会倒贴来出售一些礼物,也就是说价格可能为负数。
小Y 想给女朋友买礼物,为了表达心意,他希望购买的礼物总价不小于 L,但是也不能
买得太贵,因为总价大于 R 会惹女朋友生气。然而作为一个直男,小Y 确实不知道应该如
何选择,于是他想出了一个办法——选择若干紧邻连续的礼物进行购买。他现在希望知道自
己一共有多少种合适的购买方案。
1.2 输入格式
第一行为三个整数 n, L, R,含义如题意所述;
接下来一行 n 个整数,第 i 个整数为 pi,表示第 i 个礼物的价格。
1.3 输出格式
仅一行一个整数,表示满足条件的方案数。
1.4 样例输入
5 5 8
3 3 -2 1 3
1.5 样例输出
4
1.6 样例解释
依次对礼物编号为1,2,3,4,5,则满足条件的方案有 {1,2}, {1,2,3,4}, {1,2,3,4,5}, {2,3,4,5}。
1.7 数据范围与约定
对于前20%的数据满足 n≤1000;
对于另外20%的数据满足 pi 非负。
对于100%的数据满足1≤n≤100000,1≤L≤R≤109,|pi|≤100000。
解思
每次新加入一个数,要把前面所有数的前缀和都加上这个数,考虑前面不加而是将答案的区间平移,于是想到支持单点修改,区间动态查询的平衡树,FHQ无旋treap(有旋板子现在还没过2333),据说也有用树状数组离散化和CDQ分治的...
关于FHQ无旋treap参见【无旋treap hash】匹配(2022.5.21) _
平衡树代码如下:
#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read(){
int f=1,j=0;
char w=getchar();
while(w>'9'||w<'0'){
if(w=='-')f=-1;
w=getchar();
}
while(w>='0'&&w<='9'){
j=(j<<3)+(j<<1)+w-'0';
w=getchar();
}
return f*j;
}
const int N=100100;
int n,L,R,now,root,ans;
int ln[N],sum[N],num[N],size[N],ls[N],rs[N],tail;
inline void update(int nown){
size[nown]=size[ls[nown]]+size[rs[nown]]+ln[nown];
return ;
}
void split(int nown,int &l,int &r,int val){
if(nown==0){
l=r=0;
return ;
}
if(sum[nown]<=val)l=nown,split(rs[nown],rs[nown],r,val);
else r=nown,split(ls[nown],l,ls[nown],val);
update(nown);
return ;
}
void merge(int &k,int l,int r){
if(l==0||r==0){
k=l+r;
return ;
}
if(num[l]>num[r])k=l,merge(rs[l],rs[l],r);
else k=r,merge(ls[r],l,ls[r]);
update(k);
return ;
}
inline int newpoint(int k){
sum[++tail]=k;
ln[tail]=1;
num[tail]=rand();
return tail;
}
signed main(){
//freopen("gift.in","r",stdin);
//freopen("gift.out","w",stdout);
srand(time(NULL));
n=read();L=read();R=read();
for(int i=1;i<=n;i++){
int x=read(),y;
now+=x;y=x-now;
int l,mid=0,r;
split(root,l,r,y);
split(l,l,mid,y-1);
if(mid!=0)ln[mid]++;
else mid=newpoint(y);
update(mid);//------------
merge(root,l,mid);
merge(root,root,r);
split(root,l,r,R-now);
split(l,l,mid,L-1-now);
ans+=size[mid];
merge(root,l,mid);
merge(root,root,r);
}
printf("%lld",ans);
return 0;
}
/*
5 5 8
3 3 -2 1 3
*/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】