首页 > 其他分享 >AtCoder Beginner Contest 266 Ex Snuke Panic (2D)

AtCoder Beginner Contest 266 Ex Snuke Panic (2D)

时间:2022-10-27 10:48:50浏览次数:75  
标签:AtCoder le return Beginner Contest int ll long maxn

AtCoder 传送门

洛谷传送门

考虑 dp,\(f_i\) 设在 \(t_i\) 时刻到达第 \(i\) 个点,能获得的最大收益。

转移:\(f_i = f_j + a_i\),其中 \(j\) 能转移到 \(i\) 的充要条件有:

  • \(t_j \le t_i\)
  • \(y_j \le y_i\)
  • \(|x_i - x_j| + y_i - y_j \le t_i - t_j\)

第三个条件表示从 \(j\) 走到 \(i\) 时间要足够。

拆第三个条件的绝对值,得:

  • \(x_i - x_j + y_i - y_j \le t_i - t_j\)
  • \(x_j - x_i + y_i - y_j \le t_i - t_j\)

移项,得:

  • \(t_j - x_j - y_j \le t_i - x_i - y_i\)
  • \(t_j + x_j - y_j \le t_i + x_i - y_i\)

这样你就得到了四个条件。乍一看好像是四维偏序!但是你发现若满足 \(|x_i - x_j| + y_i - y_j \le t_i - t_j\),则一定满足 \(t_i - t_j \ge 0\),因此可以省略一个条件。

接下来跑 cdq 优化 dp 即可。

code
/*

p_b_p_b txdy
AThousandSuns txdy
Wu_Ren txdy
Appleblue17 txdy

*/

#include <bits/stdc++.h>
#define pb push_back
#define fst first
#define scd second
#define mems(a, x) memset((a), (x), sizeof(a))

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
typedef pair<ll, ll> pii;

const int maxn = 100100;
const ll inf = 0x3f3f3f3f3f3f3f3fLL;

ll n, f[maxn], lsh[maxn], tot;
struct node {
	ll t, x, y, v, z, id, k;
} a[maxn], b[maxn];

bool cmp1(node a, node b) {
	if (a.y != b.y) {
		return a.y < b.y;
	} else if (a.k != b.k) {
		return a.k < b.k;
	} else {
		return a.z < b.z;
	}
}

bool cmp2(node a, node b) {
	if (a.k != b.k) {
		return a.k < b.k;
	} else if (a.z != b.z) {
		return a.z < b.z;
	} else {
		return a.y < b.y;
	}
}

namespace BIT {
	ll c[maxn];
	
	void init() {
		for (int i = 0; i < maxn; ++i) {
			c[i] = -inf;
		}
	}
	
	void update(int x, ll d) {
		for (int i = x; i < maxn; i += (i & (-i))) {
			c[i] = max(c[i], d);
		}
	}
	
	ll query(int x) {
		ll res = -inf;
		for (int i = x; i; i -= (i & (-i))) {
			res = max(res, c[i]);
		}
		return res;
	}
	
	void clear(int x) {
		for (int i = x; i < maxn; i += (i & (-i))) {
			c[i] = -inf;
		}
	}
}

void cdq(int l, int r) {
	if (l >= r) {
		return;
	}
	int mid = (l + r) >> 1;
	cdq(l, mid);
	for (int i = l; i <= r; ++i) {
		b[i] = a[i];
	}
	sort(b + l, b + mid + 1, cmp2);
	sort(b + mid + 1, b + r + 1, cmp2);
	int p1 = l, p2 = mid + 1;
	while (p1 <= mid && p2 <= r) {
		if (b[p1].k <= b[p2].k) {
			BIT::update(b[p1].z, f[b[p1].id]);
			++p1;
		} else {
			f[b[p2].id] = max(f[b[p2].id], BIT::query(b[p2].z) + b[p2].v);
			++p2;
		}
	}
	while (p1 <= mid) {
		BIT::update(b[p1].z, f[b[p1].id]);
		++p1;
	}
	while (p2 <= r) {
		f[b[p2].id] = max(f[b[p2].id], BIT::query(b[p2].z) + b[p2].v);
		++p2;
	}
	for (int i = l; i <= mid; ++i) {
		BIT::clear(b[i].z);
	}
	cdq(mid + 1, r);
}

void solve() {
	BIT::init();
	scanf("%lld", &n);
	for (int i = 1; i <= n; ++i) {
		scanf("%lld%lld%lld%lld", &a[i].t, &a[i].x, &a[i].y, &a[i].v);
		lsh[++tot] = a[i].t + a[i].x - a[i].y;
		a[i].k = a[i].t - a[i].x - a[i].y;
		a[i].id = i;
	}
	sort(lsh + 1, lsh + tot + 1);
	tot = unique(lsh + 1, lsh + tot + 1) - lsh - 1;
	for (int i = 1; i <= n; ++i) {
		a[i].z = lower_bound(lsh + 1, lsh + tot + 1, a[i].t + a[i].x - a[i].y) - lsh + 1;
	}
	a[0].z = 1;
	sort(a + 1, a + n + 1, cmp1);
	f[0] = 0;
	for (int i = 1; i <= n; ++i) {
		f[i] = -inf;
	}
	cdq(0, n);
	printf("%lld\n", *max_element(f, f + n + 1));
}

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

标签:AtCoder,le,return,Beginner,Contest,int,ll,long,maxn
From: https://www.cnblogs.com/zltzlt-blog/p/16831335.html

相关文章

  • AtCoder Beginner Contest 201 题解
    vp情况:过了A到E,F没时间也不会。vp总结:ABC表现可以。D慢了一点,写之前大概考虑清楚每个变量或函数的意义,结构明晰才能更快的写出代码。E花的时间太长,原因......
  • D - Div Game -- ATCODER
    D-DivGamehttps://atcoder.jp/contests/abc169/tasks/abc169_d参考:https://blog.csdn.net/justidle/article/details/106474626 思路计算n中所有质数的幂,No......
  • Atcoder Grand Contest 002(A~F)
    这场打的还算舒服(虽然DE好像很久以前做过谔谔),VP赛时切掉了A~D,不过E依旧没写出来,还是太逊啦!赛时A简单分类讨论,求\(a\)到\(b\)之间数的乘积,第一眼看成了和,痛......
  • D - LRUD Instructions -- ATCODER
    D-LRUDInstructionshttps://atcoder.jp/contests/abc273/tasks/abc273_d 分析横坐标和纵坐标很大,不能采用二维数组形式,否则内存干爆,目标对象移动,按照指令进行移动......
  • AtCoder Beginners Contest 274 Editoral
    AtCoderBeginnersContest274Editoral目录AtCoderBeginnersContest274EditoralTaskA-BattingAverageProblemStatementSampleData题面翻译SourceCode解析Tas......
  • D - Longest X -- ATCODER
    D-LongestXhttps://atcoder.jp/contests/abc229/tasks/abc229_d参考:https://zhuanlan.zhihu.com/p/441875505 思路使用acc累计数组,统计每个位置之前的.的数目设......
  • April Fools Contest 2017 题解
    ANumbersJokeJoke数列,OEIS#include<bits/stdc++.h>usingnamespacestd;#define#define#define#define#define#define#define#define#define#define#define#define#define......
  • ACM ICPC 2017 Warmup Contest 1 (NCPC 2016)
    AArtwork倒跑并查集#include<bits/stdc++.h>usingnamespacestd;#define#define#define#define#define#define#define#define#define#define#define#define#define#defin......
  • 2017 United Kingdom and Ireland Programming Contest (UKIEPC 2017)
    AAlienSunset模拟#include<bits/stdc++.h>usingnamespacestd;#define#define#define#define#define#define#define#define#define#define#define#define#define#define......
  • Atcoder补题计划
    ◉ABC274F-Fishing//枚举作为左端点的鱼//每条鱼有一个在这个区间中的时间段//计算出与长度为a的区间有交集的时间的区间的权值的最大值//时间的区间(离散化......