首页 > 其他分享 >洛谷 P9936 [NFLSPC #6] 等差数列

洛谷 P9936 [NFLSPC #6] 等差数列

时间:2023-12-16 22:24:32浏览次数:33  
标签:node typedef 洛谷 ll P9936 stk NFLSPC const top

洛谷传送门

对 \((i, a_i)\) 求出下凸包,那么一条凸包的斜率非正的切线是候选答案。

只考虑切凸包上第 \(i\) 个点的切线,那么斜率的左边界是过凸包第 \(i\) 和第 \(i + 1\) 个点的直线斜率,右边界是过凸包第 \(i - 1\) 和第 \(i\) 个点的直线斜率。最优方案的切线斜率一定要么贴着左边界,要么贴着右边界,分类取个 \(\max\) 即可。

注意斜率要是整数,上/下取整处理一下即可。

时间复杂度 \(O(n)\)。

code
// Problem: P9936 [NFLSPC #6] 等差数列
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P9936
// Memory Limit: 1 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 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 = 100100;

ll n, a[maxn], stk[maxn], top;
struct node {
	ll x, y;
	node(ll a = 0, ll b = 0) : x(a), y(b) {}
} b[maxn];

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

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

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

inline ll f(ll n) {
	return n * (n + 1) / 2;
}

void solve() {
	scanf("%lld", &n);
	for (int i = 1; i <= n; ++i) {
		scanf("%lld", &a[i]);
		b[i] = node(i, a[i]);
	}
	top = 0;
	for (int i = 1; i <= n; ++i) {
		while (top >= 2 && (b[stk[top]] - b[stk[top - 1]]) * (b[i] - b[stk[top - 1]]) >= 0) {
			--top;
		}
		stk[++top] = i;
	}
	ll ans = 1e18;
	for (int i = 1; i <= top; ++i) {
		ldb l = -1.1e9, r = 0;
		if (i > 1) {
			r = min(r, (ldb)(b[stk[i]].y - b[stk[i - 1]].y) / (b[stk[i]].x - b[stk[i - 1]].x));
		}
		if (i < top) {
			l = max(l, (ldb)(b[stk[i]].y - b[stk[i + 1]].y) / (b[stk[i]].x - b[stk[i + 1]].x));
		}
		for (ll x = ceil(l); x <= r && x - l <= 2; ++x) {
			ans = min(ans, a[stk[i]] * n - x * f(stk[i] - 1) + x * f(n - stk[i]));
		}
		for (ll x = floor(r); x >= l && r - x <= 2; --x) {
			ans = min(ans, a[stk[i]] * n - x * f(stk[i] - 1) + x * f(n - stk[i]));
		}
	}
	for (int i = 1; i <= n; ++i) {
		ans -= a[i];
	}
	printf("%lld\n", ans);
}

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

标签:node,typedef,洛谷,ll,P9936,stk,NFLSPC,const,top
From: https://www.cnblogs.com/zltzlt-blog/p/17908480.html

相关文章

  • 洛谷P1824 进击的奶牛 题解 二分答案
    题目链接:https://www.luogu.com.cn/problem/P1824题目大意:本题相当于在\(n\)个数中选\(c\)个数,使得这\(c\)个数中相差最小的两个数之差尽可能地大。解题思路:我们首先可以给\(a_1\sima_n\)从小到大排一下序(这里有点贪心的思想,你会发现很多涉及贪心的问题在排序之后解......
  • 洛谷 P1217
    原题链接:一开始的思路:把数字转换成字符串类型并将字符串反转,若反转后的字符串和原来的字符串一致且该数是质数,则是回文质数。#include<bits/stdc++.h>usingnamespacestd;boolisPrime(intx){if(x<2)returnfalse;for(inti=2;i<=x/i;i++){......
  • 【洛谷 P1271】【深基9.例1】选举学生会 题解(计数排序)
    【深基9.例1】选举学生会题目描述学校正在选举学生会成员,有名候选人,每名候选人编号分别从1到,现在收集到了张选票,每张选票都写了一个候选人编号。现在想把这些堆积如山的选票按照投票数字从小到大排序。输入格式输入和以及个选票上的数字。输出格式求出排序后的选票编......
  • [NOIP2010 提高组] 关押罪犯 - 洛谷
    P1525[NOIP2010提高组]关押罪犯-洛谷|计算机科学教育新生态(luogu.com.cn)种类并查集#include<bits/stdc++.h>#definedebug(a)cout<<#a<<"="<<a<<'\n';usingnamespacestd;usingi64=longlong;typedefpair<i64,i64>......
  • 洛谷P3396 哈希冲突
    根号分治模板题#include<iostream>#include<stdio.h>#include<algorithm>#include<cstring>#include<cmath>#defineRED"\033[0;32;31m"#defineNONE"\033[m"#defineR(x)x=read()#defineFor(i,j,n)for......
  • 洛谷P4199 万径人踪灭
    题目链接考虑容斥:拿满足条件\(1\)的方案数减去满足条件\(1\)但不满足条件\(2\)的方案数就是答案。满足条件\(1\)但不满足条件\(2\)的方案可以用\(\text{Manacher}\)算法\(O(n)\)计算。对于满足条件\(1\)的总方案数,我们记\(c_i\)表示以\(i\)位置为对称轴时,......
  • 「杂题乱刷」洛谷P1216
    题目链接一道dp的入门题。\(O(2^n)\):考虑直接爆搜,可以考虑到所有情况。\(O(n^2)\):考虑\(dp\),设\(dp_{i,j}\)代表到达第\(i\)层第\(j\)个数所能达到的最大值。状态转移方程为\(dp_{i,j}=a_{i,j}+\max(dp_{i-1,j-1},dp_{i-1,j})\)。最终答案就是\(\max(dp_{n,1},d......
  • 【洛谷 P2670】[NOIP2015 普及组] 扫雷游戏 题解(模拟)
    [NOIP2015普及组]扫雷游戏题目背景NOIP2015普及组T2题目描述扫雷游戏是一款十分经典的单机小游戏。在行列的雷区中有一些格子含有地雷(称之为地雷格),其他格子不含地雷(称之为非地雷格)。玩家翻开一个非地雷格时,该格将会出现一个数字——提示周围格子中有多少个是地雷格。游戏的......
  • 【LGR-168-Div.4】洛谷入门赛 #18
    打表过样例题目描述很不幸,你遇到了不负责任的出题人。在某道试题里,共有\(N\)个测试点,组成了\(k\)个Subtask,第\(i\)个Subtask包含\(p_i\)个测试点,第\(j\)个测试点的编号为\(w_{i,j}\)。请注意,一个测试点可能属于多个Subtask。Subtask每个Subtask包含多个测......
  • 「杂题乱刷」洛谷P1544
    题目链接数字三角形的变形。直接在原来的基础上加个判断\(3\)倍的就行了。参考代码:点击查看代码#include<bits/stdc++.h>usingnamespacestd;longlongn,m,ans=-1e18,a[110][110],dp[110][110][5010];#definelc(x)x<<1#definerc(x)x<<1|1#definelowbit(x)x&-......