首页 > 其他分享 >AtCoder Beginner Contest 177 F I hate Shortest Path Problem

AtCoder Beginner Contest 177 F I hate Shortest Path Problem

时间:2023-05-11 21:57:56浏览次数:46  
标签:AtCoder typedef Beginner Contest int res long

洛谷传送门

AtCoder 传送门

设 \(f_{i,j}\) 为从第 \(1\) 行到 \((i + 1, j)\) 的最短路。

因为我们并不关心最后到达的是哪一个格子,于是强制 \(f_{i,j}\) 为必须从 \((i, j)\) 往下走一格到 \((i + 1, j)\) 的最短路。

有转移:

\[f_{i,r+1} \gets f_{i-1,j} + r + 2 - j, j \in [l, r] \]

\[f_{i,j} \gets f_{i-1,j} + 1, j \notin [l, r] \]

\([l, r]\) 表示第 \(i\) 行被 ban 掉的区间。

这个东西显然能用线段树优化。具体地,枚举到第 \(i\) 行,线段树每个叶子结点 \([j,j]\) 存 \(f_{i,j} - j\) 的最小值。对于第一种转移,区间查最小值,单点修;对于第二种转移,区间加 \(1\)。注意到 \(j \in [l,r], f_{i,j}\) 不合法,把它们加上一个 \(+\infty\) 即可。

时间复杂度线性对数。

code
// Problem: F - I hate Shortest Path Problem
// Contest: AtCoder - AtCoder Beginner Contest 177
// URL: https://atcoder.jp/contests/abc177/tasks/abc177_f
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
#define pb emplace_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 double db;
typedef long double ldb;
typedef pair<ll, ll> pii;

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

int n, m;
struct node {
	int l, r;
} a[maxn];

namespace SGT {
	ll tree[maxn << 2], tag[maxn << 2], mn[maxn << 2];
	
	inline void pushup(int x) {
		tree[x] = min(tree[x << 1], tree[x << 1 | 1]);
		mn[x] = min(mn[x << 1], mn[x << 1 | 1]);
	}
	
	inline void pushdown(int x) {
		if (!tag[x]) {
			return;
		}
		tree[x << 1] += tag[x];
		tree[x << 1 | 1] += tag[x];
		mn[x << 1] += tag[x];
		mn[x << 1 | 1] += tag[x];
		tag[x << 1] += tag[x];
		tag[x << 1 | 1] += tag[x];
		tag[x] = 0;
	}
	
	void build(int rt, int l, int r) {
		if (l == r) {
			mn[rt] = -l;
			return;
		}
		int mid = (l + r) >> 1;
		build(rt << 1, l, mid);
		build(rt << 1 | 1, mid + 1, r);
		pushup(rt);
	}
	
	void update(int rt, int l, int r, int ql, int qr, int x) {
		if (ql > qr) {
			return;
		}
		if (ql <= l && r <= qr) {
			tree[rt] += x;
			mn[rt] += x;
			tag[rt] += x;
			return;
		}
		pushdown(rt);
		int mid = (l + r) >> 1;
		if (ql <= mid) {
			update(rt << 1, l, mid, ql, qr, x);
		}
		if (qr > mid) {
			update(rt << 1 | 1, mid + 1, r, ql, qr, x);
		}
		pushup(rt);
	}
	
	void modify(int rt, int l, int r, int x, ll y) {
		if (l == r) {
			tree[rt] = min(tree[rt], y);
			mn[rt] = min(mn[rt], y - l);
			return;
		}
		pushdown(rt);
		int mid = (l + r) >> 1;
		(x <= mid) ? modify(rt << 1, l, mid, x, y) : modify(rt << 1 | 1, mid + 1, r, x, y);
		pushup(rt);
	}
	
	ll query(int rt, int l, int r, int ql, int qr) {
		if (ql <= l && r <= qr) {
			return mn[rt];
		}
		pushdown(rt);
		ll mid = (l + r) >> 1, res = inf;
		if (ql <= mid) {
			res = min(res, query(rt << 1, l, mid, ql, qr));
		}
		if (qr > mid) {
			res = min(res, query(rt << 1 | 1, mid + 1, r, ql, qr));
		}
		return res;
	}
}

void solve() {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; ++i) {
		scanf("%d%d", &a[i].l, &a[i].r);
	}
	SGT::build(1, 1, m);
	for (int i = 1; i <= n; ++i) {
		int l = a[i].l, r = a[i].r;
		SGT::update(1, 1, m, 1, l - 1, 1);
		SGT::update(1, 1, m, r + 1, m, 1);
		ll t = SGT::query(1, 1, m, l, r);
		SGT::update(1, 1, m, l, r, 2e9);
		if (r < m) {
			SGT::modify(1, 1, m, r + 1, t + r + 2);
		}
		ll res = SGT::tree[1];
		printf("%lld\n", res > 1e9 ? -1 : res);
	}
}

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

标签:AtCoder,typedef,Beginner,Contest,int,res,long
From: https://www.cnblogs.com/zltzlt-blog/p/17392356.html

相关文章

  • AtCoder Beginner Contest 152 A-E
    AtCoderBeginnerContest152A-ACorWAvoidsolve(){intn=read(),m=read();puts(n==m?"Yes":"No");}B-ComparingStringsvoidsolve(){intn=read(),m=read();if(m<n)swap(n,m);for(inti=1;i<=m;i++){......
  • 21st UESTC Programming Contest - Preliminary except BCGIKMNPR
    21stUESTCProgrammingContest-PreliminaryexceptBCGIKMNPR OK,那么长的except那我到底写了什么呢(悲,太菜啦) A.能量采集dp+组合数的应用用dp[i][j][p]表示在(i,j)这个点以连续个p结尾的路径数1.首先对于每一个A到达这个格子的方案数是{n-i+m-j\choosen-i}......
  • AtCoder 好题选做
    AtCoderRegularContest091-F-StrangeNimhttps://atcoder.jp/contests/arc091/tasks/arc091_d清北学堂讲的一道题,我艹感觉这结论很难猜啊。做这种题一定是先写爆搜打表啊,先写了一个博弈论求SG函数:然后发现了一个规律:\(\text{SG}(nk,k)=n\)。还有一个规律:当\(n<k......
  • AtCoder Beginner Contest 298 题解
    题面:https://atcoder.jp/contests/abc298/tasks_printA-JobInterview直接模拟即可。#include<bits/stdc++.h>#include<ext/pb_ds/assoc_container.hpp>#include<ext/pb_ds/tree_policy.hpp>#include<ext/pb_ds/hash_policy.hpp>usingnamespace......
  • AtCoder DP系列刷题记录
    直面自己的弱点。AFrog1简单线性\(\text{dp}\),令\(dp_i\)为跳到第\(i\)块石头的最小花费,易得:\[dp_i+=\min(|a_i-a_{i-1}|,|a_i-a_{i-2}|)\]BFrog2很快就写完了,但是一直调了十分钟,耻辱啊。如果反着跳,第\(i\)根木桩只能从第\(i+1\)或\(i+2\)木桩上跳到,则有:\[d......
  • AtCoder Beginner Contest 234 Ex Enumerate Pairs
    洛谷传送门AtCoder传送门把每个点分到\((\left\lfloor\frac{x}{K}\right\rfloor,\left\lfloor\frac{y}{K}\right\rfloor)\)的正方形内,枚举相邻正方形,计入答案。正确性显然。复杂度证明就是所有每个正方形内距离为\(K\)的点对下界为\(\Omega(n^2)\)。考虑分成四个边长为......
  • AtCoder Beginner Contest 221 F Diameter set
    洛谷传送门AtCoder传送门显然,选出的每两个点都要组成一条直径。还是显然,每条直径的重合部分只可能是一个点或一条边。简单证一下,没有重合显然不可能,重合超过一个点或一条边,直径会更长。进一步发现,设直径点数为\(x\),如果\(x\nmid2\),重合部分是一个点,否则重合部分是一条边......
  • AtCoder Beginner Contest 206(Sponsored by Panasonic)(E,F)
    AtCoderBeginnerContest206(SponsoredbyPanasonic)(E,F)E(容斥,gcd)E这个题大意就是给出一个\(l\)和一个\(r\),寻找满足以下条件的一对数\((x,y)\)的数量\(gcd(x,y)!=1\)\(gcd!=x\)并且\(gcd!=y\)(从这一句我们可以知道\(x\)不可能被\(y\)整除)那么我们可以设\(x\)是\(t\)的倍......
  • AtCoder Beginner Contest 217 G Groups
    洛谷传送门AtCoder传送门不妨钦定组之间的顺序是最小值越小的组越靠前,这样可以给每个组按顺序编号。设\(f_{i,j}\)为考虑了模\(m\)后\(<i\)的数,目前有\(j\)个非空组的方案数。转移就是枚举模\(m=i-1\)的数新开了\(k\)个组,设\(\len\)的数中模\(m=i-1......
  • [AtCoder-AT_ABC070C]题解(C++)
    PartIPreface原题目(Luogu)原题目(AtCoder)PartIISketch给定一个正整数\(N(1\leqN\leq100)\),表示时钟数量。接下来\(N\)行,每行一个正整数\(T_i(1\leqT_i\leq10^{18})\),表示每个时钟旋转\(T_i\)秒后还会回到原来的地方。求出在多少秒之后,所有时钟还会同时......