Codeforces Round 975 (Div. 1) D. Max Plus Min Plus Size(思维题 并查集/动态dp 线段树维护状态合并)

news2024/9/28 23:50:30

题目

思路来源

hhoppitree代码 + 官方题解

题解

注意到最大值一定会被取到,

对于最小值固定的话,对于1 2 3 4 5的连续段,要么贪心地取1 3 5,要么取2 4

如果最大值被包含在1 3 5里显然取1 3 5,否则换成2 4一定能取到最大值,是不劣的,

所以并查集维护每段奇数位置都取/偶数位置都取能否取到最大值

从大到小枚举最小值,把数逐渐加入并查集,实际相当于维护若干段链表

如果存在一个连续段,使得选这个连续段中较多的那一半(奇数唯一,偶数均可)能取到最大值

则答案不需要减1,否则为了取到最大值需要反选,将答案减1

代码1(并查集)

#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
#include<map>
#include<set>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i=(a);i>=(b);--i)
typedef long long ll;
typedef double db;
typedef pair<int,int> P;
#define fi first
#define se second
#define pb push_back
#define dbg(x) cerr<<(#x)<<":"<<x<<" ";
#define dbg2(x) cerr<<(#x)<<":"<<x<<endl;
#define SZ(a) (int)(a.size())
#define sci(a) scanf("%d",&(a))
#define pt(a) printf("%d",a);
#define pte(a) printf("%d\n",a)
#define ptlle(a) printf("%lld\n",a)
#define debug(...) fprintf(stderr, __VA_ARGS__)
const int N=2e5+10;
int t,n,a[N],par[N],sz[N],x[N],c,mx,can,cnt,ans;
vector<int>pos[N];
bool ok[2][N];
int find(int x){
    return par[x]==x?x:par[x]=find(par[x]);
}
bool has(int x){
    if(sz[x]&1)return ok[0][x];
    return ok[0][x] || ok[1][x];
}
void init(int x){
    par[x]=x;
    sz[x]=1;
    if(a[x]==mx)ok[0][x]=1;
    can+=has(x);
    cnt++;
}
void op(int x,int v){
    can+=v*has(x);
    cnt+=v*(sz[x]+1)/2;
}
void merge(int x,int y){//x<y
    if(!par[x] || !par[y])return;
    x=find(x),y=find(y);
    if(x==y)return;
    //printf("x:%d y:%d\n",x,y);
    op(x,-1),op(y,-1);
    int z=sz[x]&1;
    ok[0][x]|=ok[z][y];
    ok[1][x]|=ok[z^1][y];
    sz[x]+=sz[y];
    op(x,1);
    par[y]=x;
}
int main(){
    sci(t);
    while(t--){
        sci(n);
        ans=mx=c=cnt=can=0;
        rep(i,1,n){
            sci(a[i]);
            x[c++]=a[i];
            par[i]=0;
            sz[i]=0;
            ok[0][i]=ok[1][i]=0;
            mx=max(mx,a[i]);
            pos[i].clear();
        }
        sort(x,x+c);
        c=unique(x,x+c)-x;
        rep(i,1,n){
            int v=lower_bound(x,x+c,a[i])-x+1;
            pos[v].pb(i);
        }
        per(i,c,1){
            if(!SZ(pos[i]))continue;
            for(auto &v:pos[i]){
                init(v);
                if(v)merge(v-1,v);
                if(v+1<=n)merge(v,v+1);
            }
            //printf("i:%d x:%d mx:%d can:%d cnt:%d\n",i,x[i-1],mx,can,cnt);
            ans=max(ans,x[i-1]+mx+cnt-(!can));
        }
        pte(ans);
    }
    return 0;
}

代码2(动态dp 线段树维护状态合并)

不用观察到任何性质,像维护动态dp那样,直接暴力合并

f[x][i][j][k]表示线段树的x节点,最大值有没有取到,左端点有没有选,右端点有没有选,

相当于有8个状态,线段树维护状态合并即可

#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")

using namespace std;

const int N = 2e5 + 5;

int a[N], f[1 << 19][2][2][2];

void upd(int k, int l) {
    for (int i = 0; i < 2; ++i) {
        for (int j = 0; j < 2; ++j) {
            for (int K = 0; K < 2; ++K) {
                f[k][i][j][K] = -1e9;
            }
        }
    }
    f[k][0][0][0] = 0;
    if (a[l] < 0) return;
    f[k][0][1][1] = 1;
    f[k][1][1][1] = a[l] + 1;
}

void pushup(int k) {
    for (int i = 0; i < 2; ++i) {
        for (int j = 0; j < 2; ++j) {
            for (int K = 0; K < 2; ++K) {
                f[k][i][j][K] = -1e9;
            }
        }
    }
    for (int a = 0; a < 2; ++a) {
        for (int b = 0; b < (a ? 1 : 2); ++b) {
            for (int i = 0; i < 2; ++i) {
                for (int j = 0; j < 2; ++j) {
                    for (int x = 0; x < (j ? 1 : 2); ++x) {
                        for (int y = 0; y < 2; ++y) {
                            f[k][a + b][i][y] = max(f[k][a + b][i][y], f[k << 1][a][i][j] + f[k << 1 | 1][b][x][y]);
                        }
                    }
                }
            }
        }
    }
}

void build(int k, int l, int r) {
    if (l == r) {
        upd(k, l);
        return;
    }
    int mid = (l + r) >> 1;
    build(k << 1, l, mid);
    build(k << 1 | 1, mid + 1, r);
    pushup(k);
}

void update(int k, int l, int r, int x) {
    if (l == r) {
        upd(k, l);
        return;
    }
    int mid = (l + r) >> 1;
    if (x <= mid) update(k << 1, l, mid, x);
    else update(k << 1 | 1, mid + 1, r, x);
    pushup(k);
}

signed main() {
    int T; scanf("%d", &T);
    while (T--) {
        int n; scanf("%d", &n);
        vector< pair<int, int> > vec;
        for (int i = 1; i <= n; ++i) scanf("%d", &a[i]), vec.push_back({a[i], i});
        build(1, 1, n);
        sort(vec.begin(), vec.end());
        int res = 0;
        for (auto [x, y] : vec) {
            res = max(res, x + max({f[1][1][0][0], f[1][1][0][1], f[1][1][1][0], f[1][1][1][1]}));
            a[y] = -1e7;
            update(1, 1, n, y);
        }
        printf("%d\n", res);
    }
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2175150.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Tableau数据可视化入门

目录 一、实验名称 二、实验目的 三、实验原理 四、实验环境 五、实验步骤 1、Tableau界面引导 2、数据来源 3、数据预处理操作 4、制作中国各个地区的利润图表 4.1条形图 4.2气泡图 5、制作填充地球图 一、实验名称&#xff1a; 实验一&#xff1a;Tableau数据可视…

信息学奥赛复赛复习06-CSP-J2020-02直播获奖-向上取整、向下取整、整数除法、最大值、最小值、计数排序

PDF文档回复:20240928 1 2020 CSP-J 题目1 优秀的拆分 [题目描述] NOI2130 即将举行。为了增加观赏性&#xff0c;CCF 决定逐一评出每个选手的成绩&#xff0c;并直播即时的获奖分数线。本次竞赛的获奖率为 w%&#xff0c;即当前排名前 w% 的选手的最低成绩就是即时的分数线 …

Java SPI 原理、样例

在 Java 中&#xff0c;SPI&#xff08;Service Provider Interface&#xff09;全称为服务提供者接口&#xff0c;它是一种用于实现框架扩展和插件化的机制。 一、SPI 作用 允许在运行时动态地为接口查找服务实现&#xff0c;而不需要在代码中显式地指定具体的实现类。 这使得…

跨多场景帧重建DENSER:使用小波估计进行城市动态场景重构

Abstract 本文提出了一种名为DENSER的高效方法&#xff0c;该方法利用三维高斯点云(3DGS)技术来重建动态城市环境。尽管通过神经辐射场(NeRF)隐式方法和3DGS显式方法的若干场景重建技术在较复杂的动态场景中展示了出色的效果&#xff0c;但在建模前景物体的动态外观时仍存在挑…

PY32F002B

墨水屏&#xff1a; 前景和背景 在屏幕和图像处理中&#xff0c;前景和背景是两个重要的概念&#xff1a; 前景&#xff08;Foreground&#xff09;&#xff1a; 指的是图像或屏幕上最显著的部分&#xff0c;通常是用户关注的主要内容。例如&#xff0c;在一张照片中&#xf…

【开源免费】基于SpringBoot+Vue.JS技术交流分享平台(JAVA毕业设计)

博主说明&#xff1a;本文项目编号 T 053 &#xff0c;文末自助获取源码 \color{red}{T053&#xff0c;文末自助获取源码} T053&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析…

基于STM32热力二级管网远程监控系统设计(论文+源码)_kaic

摘 要 城市集中供热的运行管理中&#xff0c;热力二级管网作为供暖系统的重要的一环&#xff0c;通过对供热管网的远程集中监控、调节和对温度、压力、流量等参数的采集分析及处理&#xff0c;可以实现日常生产调度管理的自动化&#xff0c;提高运行管理效率。同时&#xff0c…

论文速递 | Management Science 8月文章合集

编者按 在本系列文章中&#xff0c;我们对顶刊《Management Science》于8月份发布文章中进行了精选&#xff08;共9篇&#xff09;&#xff0c;并总结其基本信息&#xff0c;旨在帮助读者快速洞察行业最新动态。 推荐文章1 ● 题目&#xff1a;Optimal Mechanism Design with …

TikTok不符合推荐页资格是为什么?该如何解决?

TikTok推荐页&#xff0c;就是平台上的For You一栏&#xff0c;即是TikTok的核心功能之一&#xff0c;它会根据用户的兴趣和行为推送个性化内容。然而&#xff0c;并非所有视频都有机会进入推荐页。如果你在TikTok上发布的视频显示不符合推荐页的资格&#xff0c;那么很可能是由…

记一次因视频编码无法在浏览器播放、编码视频报错问题

起因 ... f cv2.VideoWriter_fourcc(*h264) ...我这边使用h264编码会提示 OpenCV: FFMPEG: tag 0x34363268/h264 is not supported with codec id 27 and format mp4 / MP4 (MPEG-4 Part 14) OpenCV: FFMPEG: fallback to use tag 0x31637661/avc1 [ERROR:02.711] global /i…

AI模型托管数量突破百万大关

B站&#xff1a;啥都会一点的研究生公众号&#xff1a;啥都会一点的研究生 AI圈又有哪些新鲜事&#xff1f; Hugging Face AI模型托管数量突破百万大关 AI托管平台Hugging Face迎来里程碑&#xff0c;其托管的AI模型数量已超过100万个&#xff0c;标志着AI产业的蓬勃发展。H…

Java_集合_双列集合_Map

第一章Map集合 Map是双列集合顶级接口 什么叫做双列集合:一个元素有两部分构成:key和value -> 键值对 1.1.HashMap 常用方法: V put(K key, V value) -> 添加元素,返回的是被替换的value值 V remove(Object key) ->根据key删除键值对,返回的是被删除的value…

Servlet——springMvc底层原理

我们也先了解一下什么的动态资源&#xff0c;什么是静态资源。 静态资源&#xff1a;无需程序运行就可以获取的资源&#xff08;照片、html、css、js等&#xff09; 动态资源&#xff1a;需要通关程序运行才可以获得的资源。 &#xff08;其实动态、静态的资源都与Servlet有…

智慧水利综合解决方案

1. 智慧水利综合解决方案概述 智慧水利综合解决方案旨在通过集成先进技术&#xff0c;实现水利管理的智能化和高效化。该方案涵盖平台建设、业务系统建设和系统集成服务三大应用场景&#xff0c;通过数字孪生、GIS平台开发等技术手段&#xff0c;全面提升水利行业的管理能力和…

Android页面跳转与返回机制详解

在Android开发中&#xff0c;页面跳转是实现应用功能交互的重要手段之一。本文将从Activity之间的跳转、Activity与Fragment之间的跳转、Fragment之间的跳转以及页面返回的问题四个方面进行详细解析。 一、Activity之间的跳转 Activity是Android应用的基本构建块&#xff0c;…

【C++笔记】初始模版和STL简介

【C笔记】初始模版和STL简介 &#x1f525;个人主页&#xff1a;大白的编程日记 &#x1f525;专栏&#xff1a;C笔记 文章目录 【C笔记】初始模版和STL简介前言一.初始模版1.1泛型编程1.2函数模版1.3类模板 二.STL简介2.1什么是STL2.2STL的版本2.3STL的六大组件2.4STL的重要…

9.28作业

QQ登录界面的实现 代码展示 wight.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QLineEdit> #include <QPushButton> #include <QVBoxLayout> #include <QRadioButton> #include <QIcon> #include <QLabel>…

TypeScript介绍和安装

TypeScript介绍 TypeScript是由微软开发的一种编程语言&#xff0c;它在JavaScript的基础上增加了静态类型检查。静态类型允许开发者在编写代码时指定变量和函数的类型&#xff0c;这样可以在编译时捕获潜在的错误&#xff0c;而不是等到运行时才发现问题。比如&#xff0c;你…

优雅使用 MapStruct 进行类复制

前言 在项目中&#xff0c;常常会遇到从数据库读取数据后不能直接返回给前端展示的情况&#xff0c;因为还需要对字段进行加工&#xff0c;比如去除时间戳记录、隐藏敏感数据等。传统的处理方式是创建一个新类&#xff0c;然后编写大量的 get/set 方法进行赋值&#xff0c;若字…

讯飞星火编排创建智能体学习(二)决策节点

目录 概述 决策节点 文生图节点 连接节点 测试结果 概述 在上一篇博文讯飞星火编排创建智能体学习&#xff08;一&#xff09;最简单的智能体构建-CSDN博客&#xff0c;我介绍了编排创作智能体&#xff0c;这篇来介绍一下“决策节点”。 决策节点 在编排创作智能体中&…