제출 #1337899

#제출 시각아이디문제언어결과실행 시간메모리
1337899c4lBitaro, who Leaps through Time (JOI19_timeleap)C++20
0 / 100
428 ms49092 KiB
#include <bits/stdc++.h>
using namespace std;
#define f first
#define s second
// #define int long long
int inf = 2e9;
pair<int,int> a[300001], b[300001];

struct Node{
	int ipl, ipr, opl, opr, cost;
};

Node sen = {inf, inf, inf, inf ,inf};

Node tr[1200001], tr2[1200001];

Node merge(Node p, Node q){
	Node c;
	if(p.ipl==inf)return q;
	if(q.ipl==inf)return p;
	c = p;
	if(p.opr < q.ipl){
		c.ipl = c.ipr;
		c.opl = q.opl;
		c.opr = q.opl;
		c.cost += q.cost;
	}else if(p.opl > q.ipr){
		c.cost += q.cost + (c.opl - q.ipr);
		c.ipr = c.ipl;
		c.opl = q.opr;
		c.opr = q.opr;
	}else{
		c.cost += q.cost;
		int dau = max(p.opl, q.ipl), cuoi = min(p.opr, q.ipr);
		c.ipl = p.ipl+(dau-p.opl), c.ipr = p.ipr- (p.opr-cuoi);
		c.opl = q.opl + (dau-q.ipl);
		c.opr = q.opr - (q.ipr-cuoi);
	}
	return c;
}

void build(int node, int start, int end){
	if(start==end){
		tr[node] = {a[start].f, a[start].s, a[start].f, a[start].s, 0};
		tr2[node] = {b[start].f, b[start].s, b[start].f, b[start].s, 0};
	}else{
		int mid = (start+end)/2;
		build(2*node, start, mid);
		build(2*node+1, mid+1, end);
		tr[node] = merge(tr[2*node], tr[2*node+1]);
		tr2[node] = merge(tr2[2*node+1], tr2[2*node]);
	}
}

void update(int node, int start, int end, int p){
	if(start==end){
		tr[node] = {a[start].f, a[start].s, a[start].f, a[start].s, 0};
		tr2[node] = {b[start].f, b[start].s, b[start].f, b[start].s, 0};
	}else{
		int mid = (start+end)/2;
		if(p<=mid)update(2*node, start, mid, p);
		else update(2*node+1, mid+1, end, p);
		tr[node] = merge(tr[2*node], tr[2*node+1]);
		tr2[node] = merge(tr2[2*node+1], tr2[2*node]);
	}
}



Node query(int node, int start, int end, int l, int r){
	if(start > r or end<l){
		return sen;
	}
	if(l<=start and end<=r){
		return tr[node];
	}
	int mid = (start+end)/2;
	Node t = query(2*node, start, mid, l, r), p =query(2*node+1, mid+1, end, l, r);
	return merge(t, p);
}

Node query2(int node, int start, int end, int l, int r){
	if(start > r or end<l){
		return sen;
	}
	if(l<=start and end<=r){
		return tr2[node];
	}
	int mid = (start+end)/2;
	Node t = query2(2*node, start, mid, l, r), p =query2(2*node+1, mid+1, end, l, r);
	return merge(p, t);
}


signed main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	int n, q;
	cin >> n >> q;
	for (int i = 1;i<n;++i){
		int l, r;
		cin >> l >> r;
		r--;
		a[i] = {l, r};
		b[i] = a[i];
		a[i].f -= i;
		a[i].s -= i;
		b[i].f += i;
		b[i].s += i;
	}
	build(1, 1, n-1);
	while(q--){
		int t, A, B, C, D;
		cin >> t >> A >> B >> C;
		if(t==1){
			C--;
			a[A] = {B-A, C-A};
			b[A] = {B+A, C+A};
			update(1, 1, n-1, A);
		}else{
			cin >> D;
			int sol = 0;
			
			if(A<C){
				B-=A;
				Node res = query(1, 1, n-1, A, C-1);
				// for (int i = 1;i<n;++i){
					// cout << a[i].f << ' ' << a[i].s << '\n';
				// }
				// cout << res.ipl << ' ' << res.ipr << ' ' << res.opl << ' ' << res.opr << ' ' << res.cost << '\n';
				// return 0;
				sol = res.cost;
				if(B >= res.ipr){
					sol += B-res.ipr;
				}
				if(B < res.ipl){
					B = res.opl;
				}else if(B > res.ipr){
					B = res.opr;
				}else{
					B = res.opl + (B-res.ipl);
				}
				B += C;
			}else if(A>C){
				swap(A, C);
				B += C-1;
				Node res = query2(1,1, n-1, A, C-1);
				// for (int i = 1;i<n;++i){
					// cout << a[i].f << ' ' << a[i].s << '\n';
				// }
				// cout << res.ipl << ' ' << res.ipr << ' ' << res.opl << ' ' << res.opr << ' ' << res.cost << '\n';
				sol = res.cost;
				if(B >= res.ipr){
					sol += B-res.ipr;
				}
				if(B < res.ipl){
					B = res.opl;
				}else if(B > res.ipr){
					B = res.opr;
				}else{
					B = res.opl + (B-res.ipl);
				}
				B -= A;
				B++;
			}
			sol += max((int)0, B-D);
			cout << sol << '\n';
		}
	}
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...