题有点多 | 2023.6.23 做题记录

题有点多 | 2023.6.23 做题记录

CF1805D A Wide, Wide Graph

A Wide, Wide Graph

每个节点是否被删只用考虑离其最远的节点

好直觉啊

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <string>
#include <random>

typedef long long ll;
typedef unsigned long long ull;
using std::cin;
using std::cout;
using std::pair;
template<typename T, typename Ts>
inline void chkmin(T &a, Ts b) {if(a > b) a = b;}
template<typename T, typename Ts>
inline void chkmax(T &a, Ts b) {if(a < b) a = b;}

namespace Nostalgia {
	const int N = 2e5 + 10;
	const ll mod = 998244353;
	int n, tp, bt;

	//Save Graph
	std::vector<int> G[N >> 1];
	struct edge {
		int u, v;
		edge(){}
		edge(int _u, int _v) {u = _u, v = _v;}
	}E[N];
	int idx;

	inline void add(int u, int v) {
		G[u].push_back(idx), E[idx++] = edge(u, v);
	}

	int dep[N >> 1] = {-1}, mxdis[N >> 1];
	//

	void dfs(int u, int fa) {
		dep[u] = dep[fa] + 1;
		if(dep[u] > dep[tp])
			tp = u;
		chkmax(mxdis[u], dep[u]);
		for(int i : G[u]) {
			edge e = E[i];
			if(e.v == fa)
				continue;
			dfs(e.v, u);
		}
	}

	void solve() {
		cin >> n;
		for(int i = 1; i < n; i++) {
			int u, v;
			cin >> u >> v;
			add(u, v), add(v, u);
		}
		dfs(1, 0);
		dfs(tp, 0);
		dfs(tp, 0);
		std::sort(mxdis + 1, mxdis + 1 + n);
		int p = 1;
		int ans = 1;
		for(int k = 1; k <= n; k++) {
			while(k - 1 == mxdis[p]) p++, ans++;
			cout << std::min(ans, n) << ' ';
		}
	}
}
int main() {
	std::ios::sync_with_stdio(false);
	cin.tie(0);
	int T = 1;
	while(T--) {
		Nostalgia::solve();
	}
	return 0;
}

CF1795E. Explosions?

Explosions?

这啥啊。

咋想了一个多小时,我这么菜的吗?

是线段树优化DP

不妨假设 \(f_i\) 表示从 \(i\) 起爆,只考虑左边所需要的最小能量,那么我们动态维护一个单调的序列(起爆的时候令答案最小的序列)

那么如果 \(a_i>a_{i-1}\),那么显然有 \(f_i=f_{i-1}\)

如果 \(a_i<a_{i-1}\),那么我们要将 \(j\in [1, i-1]\) 中的所有值减去 \(a_{i-1}-a_i+1\),然后和 \(0\)\(\max\),具体实现可以线段树上二分,我们可以算出这个时候的代价,记为 \(t\),则

\[f_i=f_{i-1}+t \]

随后我们对称的维护一个 \(g_i\) 表示只考虑右边的最小能量,答案就是

\[\min_{i=1}^{n}(f_i+g_i+h_i) \]

因为懒了不想写双重tag的线段树,其实维护最右/左边为 \(0\) 的数然后暴力删复杂度是对的

posted @ 2023-06-26 20:31  Nelofus  阅读(13)  评论(0编辑  收藏  举报