传送门
题意
一段路上有 N N N 个点,每个点有一个合法时间段 [ u i , v i ] [u_i, v_i] [ui,vi],相邻两个点有一个长度。每次问,在 u_i 的时间从 i 出发后,能否依次经过 i + 1 ∼ j i+1 \sim j i+1∼j 的所有点,使得到达时间满足每个点的合法区间(如果提前到可以等待,迟到了失败了)。同时还可能修改一段路的长度,或者修改一个点的合法时间段。
分析
我们去用线段树维护每一段最后离开的最早时间,最晚时间,然后去和其他的节点进行合并,通过距离和时间范围判断是否合法
最后修改因为是单点修改,暴力修改即可
需要注意的是父节点与两个子节点的关系并不是简单的逻辑关系,所以在
q
u
e
r
y
query
query的时候需要将所有范围合并成一个节点返回
代码
#pragma GCC optimize(3)
#include <bits/stdc++.h>
#define debug(x) cout<<#x<<":"<<x<<endl;
#define dl(x) printf("%lld\n",x);
#define di(x) printf("%d\n",x);
#define _CRT_SECURE_NO_WARNINGS
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef vector<int> VI;
const int INF = 0x3f3f3f3f;
const int N = 1e6 + 10;
const ll mod = 1000000007;
const double eps = 1e-9;
const double PI = acos(-1);
template<typename T>inline void read(T &a) {
char c = getchar(); T x = 0, f = 1; while (!isdigit(c)) {if (c == '-')f = -1; c = getchar();}
while (isdigit(c)) {x = (x << 1) + (x << 3) + c - '0'; c = getchar();} a = f * x;
}
int gcd(int a, int b) {return (b > 0) ? gcd(b, a % b) : a;}
struct Node{
int l,r;
int u,v,w;
bool f;
}tr[N * 4];
int U[N],V[N],w[N];
int n;
Node merge(Node l,Node r,int cost)
{
Node ans;
ans.f= l.f&r.f;
if(l.u+cost> r.v) ans.f=0;
ans.u=max(r.u,l.u+cost+r.w);
ans.v=min(l.v,r.v-cost-l.w);
ans.w=l.w+r.w+cost;
return ans;
}
void build(int u,int l,int r){
tr[u] = {l,r};
if(l == r){
tr[u] = {l,r,U[l],V[l],0,1};
return;
}
int mid = l + r >> 1;
build(u << 1,l,mid);
build(u << 1 | 1,mid + 1,r);
tr[u] = merge(tr[u << 1],tr[u << 1 | 1],w[mid]);
}
Node query(int u,int l,int r){
if(tr[u].l >= l && tr[u].r <= r) return tr[u];
int mid = tr[u].l + tr[u].r >> 1;
if(r <= mid) return query(u << 1,l,r);
else if(l > mid) return query(u << 1 | 1,l,r);
else return(merge(query(u << 1,l,r),query(u << 1 | 1,l,r),w[mid]));
}
void modify(int u,int p){
if(tr[u].l == tr[u].r){
tr[u] = {p,p,U[p],V[p],0,1};
return;
}
int mid = tr[u].l + tr[u].r >> 1;
if(p <= mid) modify(u << 1,p);
else modify(u << 1 | 1,p);
tr[u] = merge(tr[u << 1],tr[u << 1 | 1],w[mid]);
}
int main() {
int T;
read(T);
while(T--){
read(n);
for(int i = 1;i <= n;i++) read(U[i]);
for(int i = 1;i <= n;i++) read(V[i]);
for(int i = 1;i < n;i++) read(w[i]);
build(1,1,n);
int q;
read(q);
while(q--){
int op;
read(op);
if(!op){
int l,r;
read(l),read(r);
if(query(1,l,r).f) puts("Yes");
else puts("No");
}
else if(op == 1){
int p;
read(p),read(w[p]);
modify(1,p);
}
else{
int p;
read(p);
read(U[p]),read(V[p]);
modify(1,p);
}
}
}
return 0;
}
/**
* ┏┓ ┏┓+ +
* ┏┛┻━━━┛┻┓ + +
* ┃ ┃
* ┃ ━ ┃ ++ + + +
* ████━████+
* ◥██◤ ◥██◤ +
* ┃ ┻ ┃
* ┃ ┃ + +
* ┗━┓ ┏━┛
* ┃ ┃ + + + +Code is far away from
* ┃ ┃ + bug with the animal protecting
* ┃ ┗━━━┓ 神兽保佑,代码无bug
* ┃ ┣┓
* ┃ ┏┛
* ┗┓┓┏━┳┓┏┛ + + + +
* ┃┫┫ ┃┫┫
* ┗┻┛ ┗┻┛+ + + +
*/