首页 > 其他分享 >AtCoder Regular Contest 164 E Segment-Tree Optimization

AtCoder Regular Contest 164 E Segment-Tree Optimization

时间:2023-07-11 22:15:31浏览次数:51  
标签:AtCoder typedef Contest ++ long int Optimization 断点

洛谷传送门

AtCoder 传送门

妙妙题。

我们考虑如何方便地描述一棵广义线段树。不难想到使用断点描述,即对于一个结点 \([l, r]\),它的左右儿子分别是 \([l, mid], [mid + 1, r]\),其中 \(mid \in [l, r - 1]\),然后把一层缩成一个 \(2^{d - 1}\) 的序列,每一层都是上层对应结点的 \(mid\),这样每对相邻断点组成了每个区间。

要令深度最小,我们将题中每个区间都拆成两个断点 \(l_i - 1, r_i\),然后我们贪心地选择这些断点作为线段树的断点的一部分。设不同断点数量为 \(k\),那么第一问的答案 \(d\) 可以轻易得知,就是最小的满足 \(2^d - 1 \ge k\) 的非负整数。因为第 \(1 \sim d\) 层共有 \(\sum\limits_{i = 1}^d 2^{i - 1} = 2^d - 1\) 个断点。

接下来我们考虑把这 \(2^d - 1\) 个断点从小到大排成一个序列,易知下标为奇数的是第 \(d\) 层的断点。我们现在要最小化第 \(d\) 层的结点访问次数之和。

设第 \(d\) 层的一个断点在 \(i \in [1, q], l_i - 1, r_i\) 中出现 \(t\) 次,可知这个断点对访问次数之和的贡献是 \(2t\)。因为这个断点两侧的区间各被访问 \(t\) 次。

然后我们可以 dp 了,设 \(f_{i, j}\) 为当前考虑到 \(1 \sim d\) 层的所有断点中,第 \(i\) 个断点,有 \(j\) 个 \(i \in [1, q], l_i - 1, r_i\) 中的断点被考虑,区间访问次数之和。根据上面得出的第 \(d\) 层断点出现次数乘 \(2\) 就是它对访问次数的贡献的结论,可以很容易地转移,考虑第 \(i\) 个断点是否是 \(i \in [1, q], l_i - 1, r_i\) 中地断点即可。注意若第 \(i\) 个断点不是第 \(d\) 层的断点,即 \(i\) 为偶数,就对访问次数没有贡献。

时间复杂度 \(O(q \log n + n^2)\)。

code
// Problem: E - Segment-Tree Optimization
// Contest: AtCoder - AtCoder Regular Contest 164
// URL: https://atcoder.jp/contests/arc164/tasks/arc164_e
// 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<int, int> pii;

const int maxn = 4040;

int n, m, f[maxn << 1][maxn], a[maxn], tot;
map<int, int> mp;

void solve() {
	scanf("%d%d", &n, &m);
	for (int i = 0, l, r; i < m; ++i) {
		scanf("%d%d", &l, &r);
		if (l > 1) {
			++mp[l - 1];
		}
		if (r < n) {
			++mp[r];
		}
	}
	for (pii p : mp) {
		a[++tot] = p.scd;
	}
	int d = 0;
	for (d = 0;; ++d) {
		if ((1 << d) - 1 >= tot) {
			break;
		}
	}
	printf("%d ", d);
	if (d == 0) {
		printf("%d\n", m);
		return;
	}
	mems(f, 0x3f);
	f[0][0] = 0;
	for (int i = 1; i < (1 << d); ++i) {
		for (int j = 0; j <= tot; ++j) {
			f[i][j] = f[i - 1][j];
			if (j) {
				f[i][j] = min(f[i][j], f[i - 1][j - 1] + ((i & 1) ? a[j] : 0));
			}
		}
	}
	printf("%d\n", f[(1 << d) - 1][tot] * 2);
}

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

标签:AtCoder,typedef,Contest,++,long,int,Optimization,断点
From: https://www.cnblogs.com/zltzlt-blog/p/17546065.html

相关文章

  • Atcoder ABC 309 F
    AtcoderABC309F题意n个盒子,长宽高为\(x,y,z,\)(长宽高是相对的,可以任意调换),问是否有一个盒子可以完全容纳另一个盒子,即存在一个\(A_i={x_i,y_i,z_i},A_j={x_j,y_j,z_j}\),使得\(x_i<x_j,y_i<y_j,z_i<z_j\)思路思考一个简单的问题:对于二元组\((x,y)\),我们怎么确定存在两......
  • AtCoder Beginner Contest 309 G Ban Permutation
    洛谷传送门AtCoder传送门前置知识:[ARC132C]AlmostSorted看\(\geX\)不顺眼,怎么办呢!直接容斥!钦定\(j\)个位置满足\(|P_i-i|<X\),其余任意,就转化成了[ARC132C]AlmostSorted。具体一点就是,你设\(f_{i,j,S}\)表示前\(i\)位有\(j\)个位置满足\(|P_i-i|<......
  • atcoder绿题选做
    ABC305:E  https://atcoder.jp/contests/abc305/tasks/abc305_e题意:给定一个无向图,给定k个守卫,每个守卫有h[i]的耐力值,如果是一个在图中是被保护的要满足和守卫的距离至少为h[i],让你升序打印所有被守卫的点解题思路:可以从守卫出发,看守卫在可以走的情况下最远走到哪,最后统计......
  • SMU Summer 2023 Contest Round 2
    SMUSummer2023ContestRound2A.TreasureHunt当\(x1-x2\)的差值与\(y1-y2\)的差值都能被\(x,y\)整除时,且商之和为2的倍数就一定可以到达#include<bits/stdc++.h>#defineendl'\n'#defineintlonglong#defineinf0x3f3f3f3fusingnamespacestd;constintN......
  • [Leetcode Weekly Contest]351
    链接:LeetCode[Leetcode]6451.找出最大的可达成数字给你两个整数num和t。如果整数x可以在执行下述操作不超过t次的情况下变为与num相等,则称其为可达成数字:每次操作将x的值增加或减少1,同时可以选择将num的值增加或减少1。返回所有可达成数字中的最大值......
  • Atcoder ABC308H Make Q
    考虑枚举唯一一个度数为\(3\)的点\(u\),即既在环上又与非环上一点相连的那个点。接下来考虑先处理环,那可以先把\(u\)从图上删掉,环的最短距离便是与\(u\)有连边的\(2\)个点在图上最短路长度加上\(2\)个点与\(u\)连边的长度,即\(\min\{w_{u,i}+w_{u,j}+\operator......
  • Atcoder ARC164B Switching Travel
    称\(c_u\not=c_v\)的边\((u,v)\)为普通边,\(c_u=c_v\)的边\((u,v)\)为特殊边。能发现若满足条件则这个环应该是由一条特殊边和若干条普通便组成的(从特殊边的一个顶点出发一直经过普通边,最后走到特殊边的另一个顶点再走回来)。于是若这个特殊边的两个顶点能只通过普通......
  • AtCoder Regular Contest 164 (A-C)
    A.TernaryDecomposition思维难度其实可以作为第二题思路先考虑最优情况下需要多少个数来组成(不够就No)在考虑全部为1的情况下是否可行(N<K这种情况不行)剩下的情况,考虑每次把高位的1向下挪变为3,所需的数字+2那么即三进制拆分后,在[min,max]范围内,且与最优情况差值为......
  • Atcoder ARC159C Permutation Addition
    设\(s=\sum\limits_{i=1}^na_i\),考虑加上排列\(p\),那么\(s\leftarrows+\frac{n\times(n+1)}{2}\)。当有解时,因为\(a_i\)相等,所以有\(s\bmodn=0\)。考虑\(n\bmod2=1\)时,\(\frac{n\times(n+1)}{2}\bmodn=0\),所以\(s\bmodn=0\)时才会有解。......
  • AtCoder Beginner Contest 309
    A:1#include<cstdio>2#include<cstring>3#include<algorithm>4#include<iostream>5#include<string>6#include<vector>7#include<stack>8#include<bitset>9#include<cstdlib>10#include......