考虑在分治时处理跨越分治中心 mid 的区间的贡献。
为了不计重,先枚举 l 计数最小值在 [l,mid] 时有贡献的 r,然后再枚举 r 计数最小值在 (mid,r] 时有贡献的 l 。处理最小值同时在[l,mid] 和 (mid,r] 的情况,则在值相等时钦定在 [l,mid] 内的值更小即可。
考虑如何计数最小值在 [l,mid] 时有贡献的 r(枚举 r 时类似)。
设当前的分治区间为 [L,R] , mnli 表示 下标在 [i,mid] 的 B 的最小值,mnri 表示 下标在 (mid,i] 的 B 的最小值,si 表示 下标在 [1,i] 的 A 的和。
则最小值在 [l,mid] 时对于 l∈[L,mid] ,一个右端点 r∈(mid,r] 有贡献,当且仅当:mnll≤mnrr 且 sr−sl−1+mnll≤S。
显然有贡献的右端点 r 是一个以 mid+1 为起点的前缀,用一个指针 ed 动态维护。
目前最优解,但本人水平有限,无法准确求出其时间复杂度和给出证明。
#include<bits/stdc++.h>
#define LL unsigned long long
#define int LL
#define ci const int
#define pb push_back
#define II inline int
#define IV inline void
#define lb lower_bound
#define re read()
#define pf printf
#define cmx(x,y) x=max(x,y)
#define cmn(x,y) x=min(x,y)
#define mt(a,b) memset(a,b,sizeof(a))
#define clr(a,n) memset(a,0,sizeof(int)*(n))
#define cpy(f,g,n) memcpy(f,g,sizeof(int)*(n))
#define f(i,x,y) for(int i=(x); i<=(y); ++i)
#define fl(i,x,y) for(int i=(x); i<(y); ++i)
#define fb(i,x,y) for(int i=(y); i>=(x); --i)
#define fe(i,v,u) for(int i=head[u],v=e[i].v; i; i=e[i].nex,v=e[i].v)
using namespace std;
#define TIM (to_string((double)(clock()-TST) / CLOCKS_PER_SEC)+" Sec")
#define MEM (to_string(fabs((&MST)-(&MED))/1024.0/1024.0)+" MiB")
const clock_t TST=clock();
bool MST;
#define edl cout<<"\n"
inline namespace Debug{
template<typename ...Args>IV err(Args ...args){
for(auto x:{args...}) cout<<x<<" "; cout<<"\n";
}
IV err_prefix(string func,int line,string args){
cout<<" | "<<func<<" : "<<line<<" - "<<"["<<args<<"] = ";
}
#define deb(args...) err_prefix(__FUNCTION__,__LINE__,#args),err(args)
}
ci N=200005;
char buf[1<<21],*p1=buf,*p2=buf;
#define gc (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
II read(){
int res=0; char c=gc;
while(c<'0'||'9'<c) c=gc;
while('0'<=c&&c<='9') res=(res<<1)+(res<<3)+(c^48),c=gc;
return res;
}
int n,mx,a[N],b[N],s[N];
LL ans;
int mn[N],c[N];
IV calc(ci l,ci r){
if(l==r) return ;
ci mid=l+r>>1;
calc(l,mid); calc(mid+1,r);
mn[mid]=a[mid]; mn[mid+1]=a[mid+1];
fb(i,l,mid-1) mn[i]=min(mn[i+1],a[i]);
f(i,mid+2,r) mn[i]=min(mn[i-1],a[i]);
//deb(l,mid,mid+1,r);
int ed;
ed=r;
fb(i,l,mid){
while(mid<ed && (s[ed]-s[i-1]+mn[i]>mx || mn[ed]<mn[i])) ed--;
while(ed<r && (s[ed+1]-s[i-1]+mn[i]<=mx && mn[ed+1]>=mn[i])) ed++;
//deb(i,ed,mid,ed-mid);
//deb(s[ed]-s[i-1]+mn[i]);
ans+=ed-mid;
}
//deb(ans);
ed=l;
f(i,mid+1,r){
while(ed<=mid && (s[i]-s[ed-1]+mn[i]>mx || mn[ed]<=mn[i])) ed++;
while(l<ed && (s[i]-s[ed-2]+mn[i]<=mx && mn[ed-1]>mn[i])) ed--;
//deb(i,mid,ed,mid-ed+1);
//deb(s[i]-s[ed-1]+mn[i]);
ans+=mid-ed+1;
}
//edl;
//deb(ans);
//edl; edl;
}
signed main(){
// freopen("in.cpp","r",stdin);
n=re; mx=re;
f(i,1,n) a[i]=re;
f(i,1,n) b[i]=re,s[i]=s[i-1]+b[i],ans+=(a[i]+b[i]<=mx);
//deb(ans);
calc(1,n);
pf("%llu",ans);
return 0;
}