首页 > 其他分享 >CodeForces 1901F Landscaping

CodeForces 1901F Landscaping

时间:2023-12-07 18:57:05浏览次数:39  
标签:node ldb int top CodeForces stk Landscaping 1901F maxn

洛谷传送门

CF 传送门

还是很有趣的一道题。场上直接暴拆式子,要维护动态凸包,本来以为是 \(\log^2\) 的,写着写着发现是 \(\log^3\),遂弃。

显然梯形面积最小等价于 \(y_0 + y_1\) 最小,而 \(y_0 + y_1\) 最小等价于梯形在 \(m = \frac{n}{2}\) 处最小。

把上凸包建出来,发现过 \(x = m\) 的线段,所在直线在 \(x = m\) 处最小。

又因为过 \(x = m\) 的线段 \(x_1 = l, x_2 = r\) 一定满足 \(l \le m < r\),所以即等价于求 \(\forall l \le m < r, (l, a_l), (r, a_r)\) 在 \(x = m\) 处的最大值

于是我们砍半,对于 \([0, m]\) 的询问,我们把 \(a\) 在 \([m + 1, n]\) 的上凸包建出来,然后对于一个询问 \(i\),我们可以二分然后取前缀 \(\max\) 处理出 \([0, i]\) 的 \(b\) 的点和上凸包的点构成的线段在 \(x = m\) 的最大值,和 \([i + 1, m]\) 的 \(a\) 的点和上凸包的点构成的线段在 \(x = m\) 的最大值。

对于 \([m + 1, n]\) 的询问类似。

所以总时间复杂度就是 \(O(n \log n)\)。

code
// Problem: F. Landscaping
// Contest: Codeforces - Educational Codeforces Round 158 (Rated for Div. 2)
// URL: https://codeforces.com/problemset/problem/1901/F
// Memory Limit: 256 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 = 200100;

ll n, a[maxn], b[maxn], m;
ldb f[maxn], g[maxn];
struct node {
	ldb x, y;
	node(ldb a = 0, ldb b = 0) : x(a), y(b) {}
} p[maxn];

int stk[maxn], top;

inline node operator - (const node &a, const node &b) {
	return node(a.x - b.x, a.y - b.y);
}

inline ldb operator * (const node &a, const node &b) {
	return a.x * b.y - a.y * b.x;
}

inline ldb calc(node a, node b) {
	ldb k = (a.y - b.y) / (a.x - b.x);
	ldb t = a.y - a.x * k;
	return k * n / 2 + t;
}

inline ldb calc(node x) {
	int l = 1, r = top;
	while (r - l > 1) {
		int mid = (l + r) >> 1;
		if (calc(x, p[stk[mid]]) < calc(x, p[stk[mid + 1]])) {
			l = mid + 1;
		} else {
			r = mid;
		}
	}
	ldb ans = -1e18;
	for (int i = l; i <= r; ++i) {
		ans = max(ans, calc(x, p[stk[i]]));
	}
	return ans;
}

void solve() {
	scanf("%lld", &n);
	--n;
	m = n / 2;
	for (int i = 0; i <= n; ++i) {
		scanf("%lld", &a[i]);
	}
	for (int i = 0; i <= n; ++i) {
		scanf("%lld", &b[i]);
	}
	for (int i = m + 1; i <= n; ++i) {
		p[i] = node(i, a[i]);
		while (top >= 2 && (p[stk[top]] - p[stk[top - 1]]) * (p[i] - p[stk[top - 1]]) >= 0) {
			--top;
		}
		stk[++top] = i;
	}
	g[m + 1] = -1e18;
	for (int i = 0; i <= m; ++i) {
		f[i] = max(i ? f[i - 1] : -1e18, calc(node(i, b[i])));
	}
	for (int i = m; i; --i) {
		g[i] = max(g[i + 1], calc(node(i, a[i])));
	}
	for (int i = 0; i <= m; ++i) {
		printf("%.12Lf ", max(f[i], g[i + 1]) * 2);
	}
	top = 0;
	for (int i = 0; i <= m; ++i) {
		p[i] = node(i, b[i]);
		while (top >= 2 && (p[stk[top]] - p[stk[top - 1]]) * (p[i] - p[stk[top - 1]]) >= 0) {
			--top;
		}
		stk[++top] = i;
	}
	f[m] = g[n + 1] = -1e18;
	for (int i = m + 1; i <= n; ++i) {
		f[i] = max(f[i - 1], calc(node(i, b[i])));
	}
	for (int i = n; i > m; --i) {
		g[i] = max(g[i + 1], calc(node(i, a[i])));
	}
	for (int i = m + 1; i <= n; ++i) {
		printf("%.12Lf ", max(f[i], g[i + 1]) * 2);
	}
}

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

标签:node,ldb,int,top,CodeForces,stk,Landscaping,1901F,maxn
From: https://www.cnblogs.com/zltzlt-blog/p/17883708.html

相关文章

  • Codeforces Round 913 (Div. 3)
    CodeforcesRound913(Div.3)div3两题新纪录..我再也不喝完酒打cf了A.Rook#include<bits/stdc++.h>//#defineintlonglong#defineendl'\n'usingnamespacestd;intboard[10][10];voidsolve(){strings;cin>>s;intx=s[0]-&#......
  • 【题解】CodeForces 1902F Trees and XOR Queries Again
    传送门:https://codeforces.com/contest/1902/problem/F数据结构题,这里讲两种思路。$ST$表思路:判定“从若干个数中能否取出其中一些,使得异或和为$x$”的问题,第一时间想到线性基,本题要做的显然就是快速求出询问路径上所有数的线性基。两组数的线性基可以合并,方法为“暴力将......
  • Educational Codeforces Round 158 (Rated for Div. 2)
    Preface补题,妈的现在EduE都做不来这搞毛啊A.LineTrip签到#include<cstdio>#include<iostream>#include<utility>#include<vector>#include<cstring>#include<cmath>#include<cstdlib>#include<algorithm>#include<queue&......
  • Codeforces Round 913 (Div. 3)(A~F)
    A.Rook题意:在一个国际象棋棋盘中,横坐标为a-h,纵坐标为1-8,字母在前,数字在后,输入一个棋子的位置,输出该棋子所在的行与列中非棋子本身位置的所有位置。分析:模拟。代码:#include<iostream>#include<algorithm>usingnamespacestd;typedeflonglongll;constintN=2e5......
  • 【题解】CodeForces 686E Optimal Point
    传送门:https://codeforces.com/contest/686/problem/E前言:本题解来源于作者某天晚上和一位朋友的发电内容(没错,这个作者直接把自己和朋友发电时发的话用markdown排了一下,传上来了),当时本来就比较口语化,加上作者的做法又实在太过离谱,因此可能语言表述不够清晰,对此深感抱歉qwq;离......
  • Codeforces Round 912 (Div. 2)
    Preface这场题莫名很对我胃口,因为F是个究极套路题,还是我最拿手的2-SAT,想+写不到半小时就搞定了然后E的核心思想和上周末VP的一场省赛的题一样,因此看一眼就会了唯一抽象的是D2要用对超集的sosdp,由于之前没写过就不知道还能这么搞A.HalloumiBoxes当\(k\ge2\)时,我们总可以通......
  • CodeForces 1497E2 Square-free division (hard version)
    洛谷传送门CF传送门感觉和CF1889C2Doremy'sDryingPlan(HardVersion)有异曲同工之妙。显然去除每个数的平方因子后,两个数相乘为完全平方数当且仅当它们相等。考虑若确定了分段方案,那么修改次数就是,每一段重复出现的数的个数。那么我们设\(f_{i,j}\)为\([1,i]\)......
  • Codeforces Round 805 (Div. 3)
    CodeforcesRound805(Div.3)基本情况A、B、C题秒了。D题一开始读错题了,以为是DP,后面发现是简单贪心,拖了点时间才AC。不过无所谓,因为E题没思路了。但是总感觉C做的太不优雅。C.TrainandQueries我的做法就纯用STL无脑模拟。跑了\(701ms\)#include<iostream>#inclu......
  • [Codeforces Round 855 (Div. 3)](https://codeforces.com/contest/1800)
    CodeforcesRound855(Div.3)A.IsItaCat?为什么这个A这么麻烦#include<bits/stdc++.h>#defineintlonglong#defineendl'\n'usingnamespacestd;voidsolve(){intn;strings;cin>>n>>s;s=""+s;......
  • Educational Codeforces Round 159 总结
    最失败的一集。C开题顺序搞错,不小心先开了C,以为是A。还好C不难。题意大概是在给定的数组最后添一个数(所有数两两不同),再自定义一个数\(k\),数组中每个数可以加上若干个\(k\),最后使得所有数字相等。要求加\(k\)的次数最少。如果不加最后一个数,那么显然把所有的数加到与最大......