首页 > 其他分享 >AtCoder Regular Contest 168 E Subsegments with Large Sums

AtCoder Regular Contest 168 E Subsegments with Large Sums

时间:2023-12-25 14:36:19浏览次数:38  
标签:AtCoder typedef Contest Subsegments mid long ge define

洛谷传送门

AtCoder 传送门

尝试二分答案,问题变为要求恰好选 \(x\) 段 \(\ge s\),最大化选的段数。

发现我们不是很会算段数的 \(\max\),因为要求段不重不漏地覆盖 \([1, n]\)。考虑给每个 \(\ge s\) 段 \([l, r]\) 一个 \(r - l\) 的代价,于是变成了算代价的 \(\min\)。此时不再要求段不重不漏地覆盖,因为我们可以把没被覆盖的部分接到旁边的 \(\ge s\) 段。

设 \(f(x)\) 为选出恰好 \(x\) 个 \(\ge s\) 的段,每一段 \([l, r]\) 的代价定义为 \(r - l\),代价的 \(\min\)。那么一个答案 \(x\) 合法当且仅当 \(f(x) \le n - k\)。

发现 \(f(x)\) 下凸(感性理解就是选的段的代价会越来越大),那么 \((x, f(x))\) 构成一个下凸包的右半边(即斜率 \(> 0\) 的部分)。套路地 wqs 二分斜率 \(k\),选一段的代价变成 \(r - l - k\),在此基础上求选出若干段的代价 \(\min\) 和在取到这个 \(\min\) 的前提下至少选了多少段即可。

上面那个问题显然可以 dp 求出。dp 数组单调,所以只用考虑最近的一个合法转移点转移过来(即对于每个 \(i\) 满足 \(\sum\limits_{k = j}^i a_k \ge s\) 的最小的 \(j\))即可。

预处理每个位置的最近合法转移点,总时间复杂度 \(O(n \log^2 n)\)。

code
// Problem: E - Subsegments with Large Sums
// Contest: AtCoder - ALGO ARTIS Programming Contest 2023 Autumn(AtCoder Regular Contest 168)
// URL: https://atcoder.jp/contests/arc168/tasks/arc168_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 mkp make_pair
#define mems(a, x) memset((a), (x), sizeof(a))

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

const int maxn = 250100;

ll n, m, K, a[maxn], b[maxn], p[maxn];
pii f[maxn];

inline pii solve(ll x) {
	for (int i = 1; i <= n; ++i) {
		f[i] = f[i - 1];
		if (p[i]) {
			f[i] = min(f[i], mkp(f[p[i] - 1].fst + i - p[i] - x, f[p[i] - 1].scd + 1));
		}
	}
	return f[n];
}

inline bool check(ll x) {
	ll l = 0, r = n, pos = -1;
	while (l <= r) {
		ll mid = (l + r) >> 1;
		if (solve(mid).scd <= x) {
			pos = mid;
			l = mid + 1;
		} else {
			r = mid - 1;
		}
	}
	return solve(pos).fst + x * pos <= n - K;
}

void solve() {
	scanf("%lld%lld%lld", &n, &K, &m);
	for (int i = 1; i <= n; ++i) {
		scanf("%lld", &a[i]);
		b[i] = b[i - 1] + a[i];
	}
	for (int i = 1, j = 0; i <= n; ++i) {
		while (b[i] - b[j] >= m) {
			++j;
		}
		p[i] = j;
	}
	ll l = 0, r = K, ans = -1;
	while (l <= r) {
		ll mid = (l + r) >> 1;
		if (check(mid)) {
			ans = mid;
			l = mid + 1;
		} else {
			r = mid - 1;
		}
	}
	printf("%lld\n", ans);
}

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

标签:AtCoder,typedef,Contest,Subsegments,mid,long,ge,define
From: https://www.cnblogs.com/zltzlt-blog/p/17926012.html

相关文章

  • CF contest 1909 Pinely Round 3 (Div. 1 + Div. 2) 题解(Vanilla的掉分赛)
    CFcontest1909PinelyRound3(Div.1+Div.2)Vanilla的掉分赛绪言PinelyRound3(Div.1+Div.2)-Codeforces\[\color{purple}\large\textbf{世界上只有一种真正的英雄主义,}\]\[\color{red}\large\textbf{就是认清了生活的真相后还依然热爱它。}\]\[\color{gray}......
  • Atcoder ABC 333 F - Bomb Game 2
    题目大意(采用0#语言):有n个人,每个人每次要么被“炸掉”,要么就被移到最后面去,概率都是1/2,求最后只剩下初始时排名为第i的人的概率。 这道题跟人数有关,而且跟位置有关。我们定义dp[i]表示一共有i个人,第i个为最后一位留下来时的概率。(不想写公式)定义j从0到i-1,表示从前面i-1......
  • AtCoder Beginner Contest 334题解
    ⭐AtCoderBeginnerContest334前言:比赛题目链接--按照惯例只写了主要部分的代码--特别说明:Rust有一个竞赛用的输入库,并且写ABC是可以用的,但是平时写洛谷是用不了的,所以我自己写了一个cin(),凑活能用,代码见下:读输入函数fncin()->String{letmutinput=String......
  • AtCoder Beginner Contest 334 G Christmas Color Grid 2
    洛谷传送门AtCoder传送门考虑相当于把每个标记点的边全部断掉,然后求连通块个数。考虑一条边\((u,v)\)(设\(u<v\))的出现时间,不难发现是\([1,u-1]\cup[u+1,v-1]\cup[v+1,n]\)。于是考虑直接套线段树分治和可撤销并查集。时空复杂度均为\(O(n^2\logn)\)......
  • AtCoder Beginner Contest 334
    A-ChristmasPresent(abc334A)题目大意给定两个数\(b,g(b\neqg)\),如果\(b\)大则输出Bat,否则输出Glove。解题思路比较大小输出即可。神奇的代码#include<bits/stdc++.h>usingnamespacestd;usingLL=longlong;intmain(void){ios::sync_with_stdio(f......
  • AtCoder 杂题精选(2023 年末)
    [ABC324G]GenerateArrays第一次知道AtCoder还有这种数据结构题。首先,所谓的“切分序列”是假,实际上只需要记录每个操作后,具体取到的原始数组的值域、下标域是什么。对于给定的下标域,求值域内数的个数,可以使用可持久化线段树,很类似区间第\(k\)大数的思路。对于操作一,考虑......
  • P9361 [ICPC2022 Xi'an R] Contests
    更好的阅读体验P9361[ICPC2022Xi'anR]Contests首先观察一下性质,每个\(l\)在每场比赛里一定是对应着某个前缀。发现题目要求的是最小的满足要求的\(l\),最暴力的大概是维护五个指针,每次答案\(+1\),然后尝试跳一步,什么时候某个前缀包含了\(x\)当前的计数器就是答案。考......
  • The 1st Universal Cup. Stage 0: Nanjing (Trial Contest)
    比赛链接题面懒得写了。A.Stop,YesterdayPleaseNoMore袋鼠移动相当于边界和洞移动。通过模拟可以得出:不考虑洞,移动后剩余袋鼠的矩形。以及假设洞在原点,移动后形成的轨迹形状。枚举洞在哪个位置,多干掉的袋鼠就是两个几何图形的交。由于洞的移动轨迹较复杂,我们考虑让它不动......
  • AtCoder Beginner Contest 333
    title:categories:算法题解description:tags:-atcoder-DFS-思维-贪心-差分-概率DP-连分数cover:/img/chino/vec/chino56.jpgkatex:truedate:2023-12-2114:47:38A-ThreeThrees(abc333A)题目大意给定一个\(0-9\)的数\(n\),输出这......
  • AtCoder_abc333
    AtCoder_abc333比赛链接A-ThreeThrees题目描述输入一个\(N\)输出\(N\)个\(N\)。解题思路(这个题但凡学过都能写出来吧)Code//Problem:A-ThreeThrees//Contest:AtCoder-ToyotaProgrammingContest2023#8(AtCoderBeginnerContest333)//URL:https://a......