ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CodeForces 1662F Antennas

2022-07-14 09:35:09  阅读:177  来源: 互联网

标签:rt le return 1662F tree CodeForces int maxn Antennas


洛谷传送门

CF 传送门

思路

边权为 \(1\) 的最短路问题,可使用 BFS 求解。当目前搜到点 \(u\) 时,瓶颈在于找出所有边 \(u \to v\),若 \(v\) 没被访问过就入队。

下面的部分和 [JOISC2020] 治療計画 有点像。考虑先拆限制中的绝对值。

  • 若 \(u < v\) ,则 \(v - u \le p_u\) 且 \(v - u \le p_v\)。此时就是在 \([u+1,u+p_u]\) 中找出所有满足 \(v - p_v \le u\) 的 \(v\) 并入队。线段树上维护 \(i \in [1,n]\),\(i - p_i\) 的最小值,找点就直接在线段树上二分,如果当前区间的 \(\min > u\) 说明区间内不可能有符合条件的点了,立即退出。

  • 若 \(u > v\) ,则 \(u - v \le p_u\) 且 \(u - v \le p_v\)。此时就是在 \([u-p_u,u-1]\) 中找出所有满足 \(v - p_v \ge u\) 的 \(v\) 并入队。线段树上维护 \(i \in [1,n]\),\(i + p_i\) 的最大值,找点也直接在线段树上二分,如果当前区间的 \(\max < u\) 说明区间内不可能有符合条件的点了,立即退出。

  • 当一个点入队时,将 \(v + p_v\) 设为 \(-\infty\),\(v - p_v\) 设为 \(\infty\)。

由于每个点只会入队一次,所以时间复杂度有保证,为 \(O(n \log n)\)。

代码

code
/*

p_b_p_b txdy
AThousandMoon txdy
AThousandSuns txdy
hxy txdy

*/

#include <bits/stdc++.h>
#define pb push_back
#define fst first
#define scd second

using namespace std;
typedef long long ll;
typedef pair<ll, ll> pii;

const int maxn = 200100;
const int inf = 0x3f3f3f3f;

int n, S, T, a[maxn], f[maxn], L[maxn], R[maxn];
queue<int> q;

struct node {
	int mx, mn;
} tree[maxn << 2];

void pushup(int x) {
	tree[x].mx = max(tree[x << 1].mx, tree[x << 1 | 1].mx);
	tree[x].mn = min(tree[x << 1].mn, tree[x << 1 | 1].mn);
}

void build(int rt, int l, int r) {
	if (l == r) {
		if (l == S) {
			tree[rt].mx = -inf;
			tree[rt].mn = inf;
		} else {
			tree[rt].mx = R[l];
			tree[rt].mn = L[l];
		}
		return;
	}
	int mid = (l + r) >> 1;
	build(rt << 1, l, mid);
	build(rt << 1 | 1, mid + 1, r);
	pushup(rt);
}

void update1(int rt, int l, int r, int ql, int qr, int x) {
	if (ql > qr) {
		return;
	}
	if (tree[rt].mn > x) {
		return;
	}
	if (l == r) {
		f[l] = f[x] + 1;
		tree[rt].mn = inf;
		tree[rt].mx = -inf;
		q.push(l);
		return;
	}
	int mid = (l + r) >> 1;
	if (ql <= mid) {
		update1(rt << 1, l, mid, ql, qr, x);
	}
	if (qr > mid) {
		update1(rt << 1 | 1, mid + 1, r, ql, qr, x);
	}
	pushup(rt);
}

void update2(int rt, int l, int r, int ql, int qr, int x) {
	if (ql > qr) {
		return;
	}
	if (tree[rt].mx < x) {
		return;
	}
	if (l == r) {
		f[l] = f[x] + 1;
		tree[rt].mn = inf;
		tree[rt].mx = -inf;
		q.push(l);
		return;
	}
	int mid = (l + r) >> 1;
	if (ql <= mid) {
		update2(rt << 1, l, mid, ql, qr, x);
	}
	if (qr > mid) {
		update2(rt << 1 | 1, mid + 1, r, ql, qr, x);
	}
	pushup(rt);
}

void solve() {
	scanf("%d%d%d", &n, &S, &T);
	for (int i = 1; i <= n; ++i) {
		scanf("%d", &a[i]);
		L[i] = max(1, i - a[i]);
		R[i] = min(n, i + a[i]);
		f[i] = 0;
	}
	build(1, 1, n);
	while (q.size()) {
		q.pop();
	}
	q.push(S);
	while (q.size()) {
		int u = q.front();
		q.pop();
		update1(1, 1, n, u + 1, R[u], u);
		update2(1, 1, n, L[u], u - 1, u);
	}
	printf("%d\n", f[T]);
}

int main() {
	int T = 1;
	scanf("%d", &T);
	while (T--) {
		solve();
	}
	return 0;
}

标签:rt,le,return,1662F,tree,CodeForces,int,maxn,Antennas
来源: https://www.cnblogs.com/zltzlt-blog/p/16476369.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有