题目描述
题解
考虑二分 b 1 b_1 b1 给 a 1 a_1 a1 为 m i d mid mid 。然后模拟,如果不能够满足 [ 2 , n ] [2,n] [2,n] ,那说明 m i d mid mid 大了,如果能够满足 [ 2 , n ] [2,n] [2,n] 但不能满足 1 1 1 ,说明 m i d mid mid 小了。
考虑二分的可行性,如果说 m i d mid mid 不能够满足 [ 2 , n ] [2,n] [2,n] ,那比 m i d mid mid 大的更无法满足 [ 2 , n ] [2,n] [2,n] ;如果 m i d mid mid 不能满足 1 1 1 ,那比 m i d mid mid 小的更无法满足,因此二分很可行。
效率: O ( n l o g M ) O(nlogM) O(nlogM) 。
官方题解好像是 O ( n ) O(n) O(n) ,还没看qwq。
代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int T,n,a[N],b[N],c[N];
#define LL long long
int J(int x){
c[1]=b[1]-x;
for (int i=2;i<=n;i++){
if (c[i-1]>=a[i]) c[i]=b[i];
else if (c[i-1]+b[i]>=a[i])
c[i]=c[i-1]+b[i]-a[i];
else return 0;
}
if (c[n]+x>=a[1]) return 1;
return 2;
}
void work(){
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
for (int i=1;i<=n;i++) scanf("%d",&b[i]);
int l=0,r=b[1];
while(l<=r){
int mid=(l+r)>>1,u;
u=J(mid);
if (!u) r=mid-1;
else if (u==1){
puts("YES");
return;
}
else l=mid+1;
}
puts("NO");
}
int main(){
for (scanf("%d",&T);T--;work());
return 0;
}