思路:
考虑如何合并两个相邻的区间,假色表示从出发允许最早的时间,表示从出发允许最晚的时间,表示从到需要的时间。
比较和能否和并,其实只需要满足。有没有其它的判断方式呢,有,但是没必要:。(这不是没事找事吗,主要是补题的时候想换个思路写,想通过维护一个和一个来完成合并,画个图就知道这样比较冗余)。
所以我们需要维护区间的,同时维护一个表示到需要的时间,主要用来更新合并后的。
code:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=1e6+7,mod=1e9+7; struct node{ int _min,_max,sum; }t[maxn<<2]; #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 int u[maxn],v[maxn],co[maxn]; node merge(node l,node r,int mid) { node x; x.sum=l.sum+r.sum+co[mid]; x._max=min(l._max,r._max-co[mid]-l.sum);//取上界的最小值 x._min=max(r._min,l._min+co[mid]+r.sum);//取下界的最大值 if(l._min+co[mid]>r._max) x._max=-1e9;//小区间不能合并,大区间也不能合并 return x; } inline void build(int l,int r,int rt) { if(l==r) { t[rt]._max=v[l]; t[rt]._min=u[r];//u[r]==u[l] t[rt].sum=0; return; } int mid=(l+r)/2; build(lson); build(rson); t[rt]=merge(t[rt<<1],t[rt<<1|1],mid); } void update(int l,int r,int rt,int x) { if(l==r) { t[rt]._max=v[l]; t[rt]._min=u[r];//u[r]==u[l] t[rt].sum=0; return; } int mid=(l+r)/2; if(mid>=x) update(lson,x); else update(rson,x); t[rt]=merge(t[rt<<1],t[rt<<1|1],mid); } node qry(int l,int r,int rt,int x,int y) { if(l>=x&&r<=y) return t[rt]; int mid=(l+r)/2; if(mid>=y) return qry(lson,x,y); else if(mid<x) return qry(rson,x,y); else return merge(qry(lson,x,y),qry(rson,x,y),mid); } inline void solve() { int n; cin>>n; for(int i=1;i<=n;++i) cin>>u[i]; for(int i=1;i<=n;++i) cin>>v[i]; for(int i=1;i<n;++i) cin>>co[i]; build(1,n,1); int Q,op,x,y; cin>>Q; while(Q--) { cin>>op; if(!op) { cin>>x>>y; node cur=qry(1,n,1,x,y); if(cur._max<u[x]) cout<<"No\n"; else cout<<"Yes\n"; } else if(op&1) { cin>>x; cin>>co[x]; update(1,n,1,x); } else { cin>>x; cin>>u[x]>>v[x]; update(1,n,1,x); } } } int main() { ios::sync_with_stdio(0);cin.tie(nullptr);cout.tie(nullptr); int _=1; cin>>_; while(_--) solve(); return 0; }