NC11166 J.Journey among Railway Stations(线段树+两点)
目录
Description
有 \(n\) 个站台,每个站台都有一个可以通过的时间 \([u_i,v_i]\) ,每两个站台之间有一条路径,共 \(n-1\) 条,\(Q\) 次询问区间 \([l,r]\),从 \(u_l\) 时间出发能否通过 \(r\) 站台
State
\(1<=T<=10^4\)
\(2<=n<=10^6\)
\(1<=u<=v<=10^9\)
\(1<=cost<=10^9\)
\(1<=Q<=10^6\)
Input
1
5
1 2 3 4 5
3 4 5 6 7
1 1 1 1
5
0 1 5
1 1 3
0 1 5
2 2 2 3
0 1 5
Output
Yes
Yes
No
Solution
假设有三个站台 \([u_1,v_1],[u_2,v_2],[u_3,v_3]\)
他们分别满足的条件为
\[u_1<=v_1 \\
max(u_1+d_1,u_2)<=v_2 \\
max(u_1+d_1+d_2,u_2+d_2,u_3)<=v_3 \\
\]
根据这些条件,可以在 \(O(n)\) 内查询出是否可以通过,但这还远远不够;
但目前为止,并没有很好的解决办法,但是如果变成以下的式子
\[u_1+d_1+d_2<=v_1+d_1+d_2 \\
max(u_1+d_1+d_2,u_2+d_2)<=v_2+d_2 \\
max(u_1+d_1+d_2,u_2+d_2,u_3)<=v_3 \\
\]
题目就有迹可循了,如果相邻的两个节点 \(i,j\) 可以通过,那么一定有 \(u_i<=v_j\)
Code
const int N = 1e6 + 5;
int n, m, k, _;
int a[N];
int b[N];
struct Node
{
ll minn, maxx;
ll lazy;
bool ok;
// Node(ll minn = 0, ll maxx = 0, ll lazy = 0, bool ok = 0) : minn(minn), maxx(maxx), lazy(lazy), ok(ok){}
#define lson id << 1
#define rson id << 1 | 1
void update(ll x)
{
maxx += x;
minn += x;
lazy += x;
}
}t[N << 2];
int c[N];
ll sum[N];
Node merge(Node a, Node b)
{
Node ans;
ans.maxx = max(a.maxx, b.maxx);
ans.minn = min(a.minn, b.minn);
ans.ok = a.ok && b.ok;
if(a.maxx > b.minn) ans.ok = 0;
return ans;
}
void push_up(int id)
{
ll x = t[id].lazy;
t[id] = merge(t[lson], t[rson]);
t[id].lazy = x;
}
void push_down(int id)
{
ll x = t[id].lazy;
if(x){
t[lson].update(x);
t[rson].update(x);
t[id].lazy = 0;
}
}
void build(int l, int r, int id)
{
t[id].ok = t[id].lazy = 0;
if(l == r){
t[id].maxx = sum[l] + a[l];
t[id].minn = sum[l] + b[l];
t[id].ok = 1;
}
else{
int mid = l + r >> 1;
build(l, mid, lson);
build(mid + 1, r, rson);
push_up(id);
}
}
void update(int l, int r, ll ca, ll cb, int id, int opt, int L = 1, int R = n)
{
if(L >= l && r >= R){
if(opt){
t[id].maxx += ca;
t[id].minn += cb;
}
else t[id].update(ca);
}
else{
int mid = L + R >> 1;
push_down(id);
if(mid >= l) update(l, r, ca, cb, lson, opt, L, mid);
if(r >= mid + 1) update(l, r, ca, cb, rson, opt, mid + 1, R);
push_up(id);
}
}
Node query(int l, int r, int id, int L = 1, int R = n)
{
if(L == l && R == r){
return t[id];
}
else{
int mid = L + R >> 1;
push_down(id);
if(mid >= r) return query(l, r, lson, L, mid);
else if(l >= mid + 1) return query(l, r, rson, mid + 1, R);
else return merge(query(l, mid, lson, L, mid), query(mid + 1, r, rson, mid + 1, R));
}
}
signed main()
{
//IOS;
rush(){
sd(n);
rep(i, 1, n) sd(a[i]);
rep(i, 1, n) sd(b[i]);
rep(i, 1, n - 1) sd(c[i]);
sum[n] = 0;
for(int i = n - 1; i; i --) sum[i] = sum[i + 1] + c[i];
build(1, n, 1);
sd(m);
int x, y, pos, w, opt;
while(m --> 0){
sd(opt);
if(opt == 0){
sdd(x, y);
bool ok = query(x, y, 1).ok;
// dbg(query(x, y, 1).maxx);
// dbg(query(x, y, 1).minn);
if(ok) puts("Yes");
else puts("No");
}
else if(opt == 1){
sdd(pos, w);
//for(int i = 1; i <= pos; i ++) update(i, i, w - c[pos], w - c[pos], 1, 1);
update(1, pos, w - c[pos], w - c[pos], 1, 0);
c[pos] = w;
}
else{
sddd(pos, x, y);
update(pos, pos, x - a[pos], y - b[pos], 1, 1);
a[pos] = x;
b[pos] = y;
}
}
}
//PAUSE;
return 0;
}

浙公网安备 33010602011771号