首页 > 其他分享 >洛谷 P6821 [PA2012]Tanie linie

洛谷 P6821 [PA2012]Tanie linie

时间:2023-06-12 15:11:53浏览次数:54  
标签:cnt 洛谷 val ll PA2012 typedef long P6821 maxn

洛谷传送门

考虑恰好选 \(k\) 个子段怎么做。

设恰好选 \(i\) 个子段的和最大值为 \(h_k\)。可以得到 \(h_{i + 1} - h_i \le h_i - h_{i - 1}\),因为 \(h_i \to h_{i + 1}\) 的过程就是多选一个子段,贡献肯定不如上一次选即 \(h_{i - 1} \to h_i\) 大。如果它不成立,那我们可以交换 \(h_{i - 1} \to h_i\) 和 \(h_i \to h_{i + 1}\) 选的段从而得到更大的 \(h_k\),矛盾。

那么 \((i, h_i)\) 构成一个上凸包。接下来是经典的 wqs 二分,二分直线斜率切这个上凸包,dp 一遍求出最大截距,这样二分即可找到过 \((k, h_k)\) 且与上凸包相切的直线方程,就能得到 \(h_k\)。

dp 的过程是平凡的。设 \(f_i\) 为 \([1, i]\) 个中选了若干个子段,它们的和最大值,设 \(g_i\) 为在取到最大值的基础上,选的段数最小值。因为当有一些点和 \((k, h_k)\) 共线时,我们希望最后算出来是最左边的点,从而得到这条直线。

\(f_i\) 有转移 \(f_i = \max(f_{i - 1}, \max\limits_{j = 1}^i (f_{j - 1} + \sum\limits_{p = j}^i a_p))\)。令 \(b_i = \sum\limits_{j = 1}^i a_j\),维护前缀最大的 \(f_i - b_i\) 和在它最大的基础上最小的 \(g_i\),dp 即可做到 \(O(n)\)。

如果只是限制最多选 \(k\) 个,那如果 \((k, h_k)\) 在左半边(即最高点的左边),那 \(\forall i \in [1, k), h_k \ge h_i\),当作恰好 \(k\) 个处理即可;如果它在右半边,二分斜率时下界设置为 \(0\),那么它就不能被截到。这种情况,直接求出 \(\max\limits_{i = 1}^n h_i\) 即可。这里也可以用上面的 dp 方法。

总时间复杂度 \(O(n \log V)\),\(V\) 是值域。

code
// Problem: P6821 [PA2012]Tanie linie
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P6821
// Memory Limit: 256 MB
// Time Limit: 1000 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 = 1000100;
const ll inf = 0x3f3f3f3f3f3f3f3fLL;

ll n, m, a[maxn], b[maxn], f[maxn], g[maxn];

inline pii calc(ll x) {
	ll mx = 0, cnt = 1;
	for (int i = 1; i <= n; ++i) {
		f[i] = f[i - 1];
		g[i] = g[i - 1];
		ll val = mx + b[i] - x;
		if (val > f[i]) {
			f[i] = val;
			g[i] = cnt;
		} else if (val == f[i]) {
			g[i] = min(g[i], cnt);
		}
		val = f[i] - b[i];
		if (val > mx) {
			mx = val;
			cnt = g[i] + 1;
		} else if (val == mx) {
			cnt = min(cnt, g[i] + 1);
		}
	}
	return make_pair(f[n], g[n]);
}

void solve() {
	scanf("%lld%lld", &n, &m);
	for (int i = 1; i <= n; ++i) {
		scanf("%lld", &a[i]);
		b[i] = b[i - 1] + a[i];
	}
	ll l = 0, r = 2e9, ans = -inf;
	while (l <= r) {
		ll mid = (l + r) >> 1;
		pii p = calc(mid);
		if (p.scd <= m) {
			ans = p.fst + m * mid;
			r = mid - 1;
		} else {
			l = mid + 1;
		}
	}
	if (ans == -inf) {
		ans = calc(0).fst;
	}
	printf("%lld\n", ans);
}

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

标签:cnt,洛谷,val,ll,PA2012,typedef,long,P6821,maxn
From: https://www.cnblogs.com/zltzlt-blog/p/17475071.html

相关文章

  • 洛谷P5322 [BJOI2019] 排兵布阵
    题目大意有s名对手,n座城堡,你有m名士兵如果一名玩家向第\(i\)座城堡派遣的士兵数严格大于对手派遣士兵数的两倍,那么这名玩家就占领了这座城堡,获得\(i\)分。求最大得分数据范围对于\(10\%\)的数据:\(s=1,n\le3,m\le10\)对于\(20\%\)的数据:\(s=1,n\le10,m\le1......
  • 【若归】 【LGR-142-Div.4】洛谷入门赛 #13赛后反思
    比赛链接:【LGR-142-Div.4】洛谷入门赛#13rk288,比前几次差(可能是因为rated?)A十年OI一场空,不开longlong见祖宗#include<bits/stdc++.h>usingnamespacestd;intmain(){ longlongintn; cin>>n; cout<<"8"<<12*(n-2)<<""<<6*(n-......
  • 洛谷 P6003 总结
    题目:洛谷P6003链接:洛谷,逐月题意有一个人欠了别人\(n\)单位牛奶,每一天他会还\(y=\max(m,\frac{n-g}{x})\)单位,\(g\)为之前还的牛奶,请求出最大的\(x\)使得这个人在\(k\)天后能换至少\(k\)单位牛奶。\(1\len,m,k\le10^{12},km<n\)。思路暴力......
  • 【LGR-141-Div.2】洛谷 6 月月赛 I (前两题)
    T1:金盏花传送门直接暴力枚举前6位的值即可,记得开longlong#include<bits/stdc++.h>usingnamespacestd;#defineintlonglonginty,z,ans=1e18;signedmain(){ scanf("%lld%lld",&y,&z); for(inti=100000;i<=999999;i++){ intx=i*1000000+y; ans=min......
  • 洛谷P1587 [NOI2016] 循环之美
    原文链接:[sol]P1587[NOI2016]循环之美-icyM3tra'sBlog此为备份。题目传送门0.前言提供一种式子较为简洁且不算难写的做法。以及介绍一种较为优秀的dp版杜教筛实现。1.式子推导我们知道纯循环小数一定可以写成分母形如\(k^a-1\)的分数。因此约分后的分母一定......
  • 洛谷 P3723 [AH2017/HNOI2017]礼物
    由题面可得:\[E_j=\sum_{i=1}^{j-1}\frac{q_i}{(i-j)^2}-\sum_{i=j+1}^{n}\frac{q_i}{(i-j)^2}\]令\(q_0=0\),并将没有意义的分式的值视为\(0\),则有:\[E_j=\sum_{i=0}^j\frac{q_i}{(i-j)^2}-\sum_{i=j}^n\frac{q_i}{(i-j)^2}\]令\(A(i)......
  • 海底高铁(洛谷3406)
         #include<iostream>usingnamespacestd;constintN=100010;intp[N];//要去的城市intA[N],B[N],C[N];longlongs,ans[N];//ans差分数组intmain(){intN,M;scanf("%d%d",&N,&M);for(inti=1;i<=M......
  • 洛谷3397地毯
        问题分析:这个比y总的二维差分模板要简单一些,因为他一开始的矩阵都为0,而且矩阵是一个n方阵,那么其实可以用y总的模板来写,下面是二维差分矩阵的原理  #include<iostream>usingnamespacestd;constintN=1010;intb[N][N];voidinsert(intx1,in......
  • 洛谷 P9344. 去年天气旧亭台
    去年天气旧亭台题目背景依旧是过往的天气,过往的楼台烟雨。时间悄悄流逝着,山河仍在,人却已不是过去的人……题目描述登上楼台,旧时满面沉灰的地板映入眼帘。共有$n$块地板,地板分为两类,第$i$块地板的类别用$c_i$表示,积灰程度用$a_i$表示。注意$c_i$为$0$或$1$。现......
  • 洛谷 P9248 - [集训队互测 2018] 完美的集合
    显然,如果选择的\(k\)个“合法集合”固定了,那么可以放置装置的点如果存在,那么必然形成一个连通块,也就是说,答案等于所有合法方案中,可以放置装置的点形成的连通块个数之和。而根据点减边的套路,这等价于,枚举每个点,计算有多少种方案满足可以在其放置装置,再枚举每条边,计算有多少种方案......