题意:有n个火车站点,第i个站点可以入站出站的时间为[ui,vi],到达下一站需要时间cost[i],需要我们实现三种操作:①询问从站点1出发,能否顺利通过l,l+1,…,r站点②修改cost[i]的值③修改ui,vi的值
解法:线段树,没什么可展开讲的,看代码就可以理解了
节点形式为:
struct node {
int flag;
ll minx, maxy, usetime;
};
flag:次节点能否通过
minx:这个节点到达下一站的最早时间
maxy:到达这个节点允许的最晚时间
AcCode
#include<algorithm>
#include<iostream>
#include<cstdio>
#define ll long long
using namespace std;
const int N = 1000005;
struct node {
int flag;
ll minx, maxy, usetime;
};
node point[N * 4];
int u[N], v[N], cost[N];
inline ll min(ll a, ll b) { return (a < b) ? a : b; }
inline ll max(ll a, ll b) { return (a > b) ? a : b; }
inline int lc(int x) { return x * 2; }
inline int rc(int x) { return (x * 2 + 1); }
inline node marge(node a, node b) {
node ret;
if (b.maxy < a.minx) ret.flag = 0;
else ret.flag = (a.flag & b.flag);
ret.usetime = a.usetime + b.usetime;//路上花费时间
ret.minx = max(a.minx + b.usetime, b.minx);//到达下一站的最小时间
ret.maxy = min(a.maxy, b.maxy - a.usetime);//最晚进站时间
return ret;
}
inline void build(int now, int l, int r) {
if (l == r) {
point[now].flag = 1;
point[now].minx = u[l] + cost[l];
point[now].maxy = v[l];
point[now].usetime = cost[l];
return;
}
int mid = (l + r) >> 1;
build(lc(now), l, mid);
build(rc(now), mid + 1, r);
point[now] = marge(point[lc(now)], point[rc(now)]);
}
inline node query(int now, int l, int r, int ql, int qr) {
//if(point[now].flag) return point[now];//返回后还要合并
if (ql <= l && qr >= r) return point[now];
int mid = (l + r) >> 1;
if (qr <= mid) return query(lc(now), l, mid, ql, qr);
else if (ql > mid) return query(rc(now), mid + 1, r, ql, qr);
else return marge(query(lc(now), l, mid, ql, qr), query(rc(now), mid + 1, r, ql, qr));
return point[now];
}
inline void changCost(int now, int l, int r, int index) {
if (l == r) {
point[now].flag = 1;
point[now].usetime = cost[l];
point[now].minx = u[l] + cost[l];
point[now].maxy = v[l];
return;
}
int mid = (l + r) >> 1;
if (index <= mid) changCost(lc(now), l, mid, index);
else changCost(rc(now), mid + 1, r, index);
point[now] = marge(point[lc(now)], point[rc(now)]);
}
signed main() {
//std::ios::sync_with_stdio(false);
//std::cin.tie(0);
int t;
scanf("%d", &t);
//std::cin >> t;
while (t--) {
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++) scanf("%d", &u[i]);
for (int i = 1; i <= n; i++) scanf("%d", &v[i]);
for (int i = 1; i < n; i++) scanf("%d", &cost[i]);
build(1, 1, n);
int q;
scanf("%d", &q);
while (q--) {
int sign;
scanf("%d", &sign);
if (sign == 0) {
int ql, qr; scanf("%d %d", &ql, &qr);
if (query(1, 1, n, ql, qr).flag)printf("Yes\n");
else printf("No\n");
}
else if (sign == 1) {
int index, val; scanf("%d %d", &index, &val);
cost[index] = val;
changCost(1, 1, n, index);
}
else {
int index, p, q; scanf("%d %d %d", &index, &p, &q);
u[index] = p;
v[index] = q;
changCost(1, 1, n, index);
}
}
}
}