RT,自己搓了几组都是对的,但交上去几乎全是 RE。
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
typedef long long ll;
const int maxn=2e5+5;
struct node{
int ls,rs,siz,dat;
ll key;
}t[maxn];
ll pre[maxn],sum[maxn],d[maxn],a[maxn],S;
int b[maxn],tot,root,n,seed=25476841;
int rnd(){
int ret=seed;
seed=(seed*7ll+13)%1000000007;
return ret;
}
int random(int N){
return (long long)rnd()*rnd()%N+1;
}
int New(ll key){
t[++tot]=(node){0,0,1,random(998244353),key};
return tot;
}
void pushup(int p){
t[p].siz=t[t[p].ls].siz+t[t[p].rs].siz+1;
}
void split(int x,ll key,int &p,int &q){
if(!x){
p=q=0;
return;
}
if(t[x].key<=key){
p=x;
split(t[x].rs,key,t[x].rs,q);
}
else{
q=x;
split(t[x].ls,key,p,t[x].ls);
}
pushup(x);
}
int merge(int x,int y){
if(!x||!y) return x|y;
if(t[x].dat<t[y].dat){
t[x].rs=merge(t[x].rs,y);
pushup(x);
return x;
}
t[y].ls=merge(x,t[y].ls);
pushup(y);
return y;
}
void insert(ll key){
int x,y;
split(root,key-1,x,y);
root=merge(merge(x,New(key)),y);
}
void remove(ll key){
int x,y,z;
split(root,key-1,x,y);
split(y,key,y,z);
if(y) y=merge(t[y].ls,t[y].rs);
root=merge(x,merge(y,z));
}
int get(ll key){
int x,y,ans;
split(root,key,x,y);
ans=t[x].siz;
root=merge(x,y);
return ans;
}
ll solve(int l,int r){
if(l==r) return a[l]+b[l]<=S;
int mid=l+r>>1,j=mid+1;
ll ret=0,suf=1e18,s=0;
vector<ll>v;
pre[mid]=1e18;
sum[mid]=0;
for(int i=mid+1;i<=r;i++){
pre[i]=min(pre[i-1],a[i]);
sum[i]=sum[i-1]+b[i];
d[i]=pre[i]+sum[i];
insert(d[i]);
}
for(int i=mid;i>=l;i--){
suf=min(suf,a[i]);
s+=b[i];
while(j<=r&&pre[j]>suf){
v.push_back(sum[j]);
remove(d[j]);
j++;
}
if(!v.empty()) ret+=(upper_bound(v.begin(),v.end(),S-s-suf)-v.begin());
ret+=get(S-s);
}
for(int i=j;i<=r;i++) remove(d[i]);
return ret+solve(l,mid)+solve(mid+1,r);
}
int main(){
scanf("%d%lld",&n,&S);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
for(int i=1;i<=n;i++)
scanf("%d",&b[i]);
printf("%lld",solve(1,n));
return 0;
}