2023ICPC网络预选赛 ( 2 ) (2) C.Covering【2-SAT、前后缀虚拟节点区间连边】

C.Covering

1

题意

给定一个长度为 n n n 的正整数数组 a a a,现在要从中选择一些下标,满足:

  1. 对于每个下标 i i i i i i i − 1 i - 1 i1 至少 有一个被选
  2. 对于所有选择的下标,任意两个下标 i , j ( i ≠ j ) , a [ i ] ≠ a [ j ] 或 a [ i + 1 ] ≠ a [ j + 1 ] i,j(i \neq j),\hspace{4pt} a[i] \neq a[j] 或 a[i + 1] \neq a[j+1] i,j(i=j),a[i]=a[j]a[i+1]=a[j+1]
  3. 不能选择下标 n n n

分析可以发现:下标 1 1 1 一定要被选,因为它前面没有下标了,下标 n − 1 n - 1 n1 一定要被选,因为下标 n n n 不能选

考虑 2 − S A T 2-SAT 2SAT

  • 对于限制 1 1 1:连边 i ˉ → i − 1 \bar i \rarr i - 1 iˉi1 i ˉ → i + 1 \bar i \rarr i + 1 iˉi+1
  • 对于限制 2 2 2:连边 i → 集合 S i \rarr 集合 S i集合S,集合 S = ( j , ∀ j ≠ i , a [ j ] = a [ i ] ∧ a [ j + 1 ] = a [ i + 1 ] ) S = (j, \forall j \neq i, \hspace{3pt} a[j] = a[i] \wedge a[j + 1] = a[i + 1]) S=(j,j=i,a[j]=a[i]a[j+1]=a[i+1])
  • 由于 1 1 1 必选, n n n 必不选,因此可以连边: 1 ˉ → 1 \bar 1 \rarr 1 1ˉ1 n → n ˉ n \rarr \bar n nnˉ,用以确定是否存在可行解

如果对于限制 2 2 2 暴力连边,复杂度太高,考虑优化:

可以发现对于每种键值 ( a [ i ] , a [ i + 1 ] ) (a[i], a[i + 1]) (a[i],a[i+1]),它们要连的集合都是除了自己本身以外的拥有相同键值的所有点,这里会分割成一个前缀后缀

2
例如上图, A A A 值表示拥有这个键值的所有下标(前面下划线表示反变量) A 3 A_3 A3 需要连接 A ˉ 1 \bar A_1 Aˉ1 A ˉ 2 \bar A_2 Aˉ2,我们只需要将其连向 p r e 2 pre_2 pre2 A 3 → p r e 2 A_3 \rarr pre_2 A3pre2 就可以完成前缀的连边,同时 p r e 3 → A ˉ 3 pre_3 \rarr \bar A_3 pre3Aˉ3 p r e 3 → p r e 2 pre_3 \rarr pre_2 pre3pre2,以便后续相同键值的连边

后缀也是类似

需要注意的是:新建虚拟节点并不是严格按照正反变量的奇偶位置来排列的,而是紧挨着
所以我们判断可行解,只需要判断到 n n n 即可,否则会因为虚拟节点而干扰正确答案!

#include<bits/stdc++.h>
#define fore(i,l,r)	for(int i=(int)(l);i<(int)(r);++i)
#define fi first
#define se second
#define endl '\n' 
#define ull unsigned long long
#define sz(x) (int)x.size()const int INF=0x3f3f3f3f;
const long long INFLL=0x3f3f3f3f3f3f3f3fLL;typedef long long ll;struct TwoSat {int n; //属性数量std::vector<std::vector<int>> e;std::vector<bool> ans;TwoSat(int n) : n(n), e(2 * n), ans(n) {} //下标从0开始/* 建边表示 u为f 且 v为g */void addedge(int u, bool f, int v, bool g) { //原变量和反变量相邻放e[2 * u + !f].push_back(2 * v + g); //反变量在偶数位置,原变量在奇数位置e[2 * v + !g].push_back(2 * u + f);}bool satisfiable(int nn) {std::vector<int> id(2 * n, -1), dfn(2 * n, -1), low(2 * n, -1);std::vector<int> stk;int now = 0, cnt = 0;std::function<void(int)> tarjan = [&](int u) {stk.push_back(u);dfn[u] = low[u] = now++;for (auto v : e[u]) {if (dfn[v] == -1) {tarjan(v);low[u] = std::min(low[u], low[v]);} else if (id[v] == -1) {low[u] = std::min(low[u], dfn[v]);}}if (dfn[u] == low[u]) {int v;do {v = stk.back();stk.pop_back();id[v] = cnt;} while (v != u);++cnt;}};for (int i = 0; i < 2 * n; ++i) if (dfn[i] == -1) tarjan(i);for (int i = 0; i < nn; ++i) {if (id[2 * i] == id[2 * i + 1]) return false;ans[i] = id[2 * i] > id[2 * i + 1]; //取依赖性更高的那个}return true;}std::vector<bool> get_ans() { return ans; }
};const ll P = 1000001;
const int N = 200050;int yes(int x) {return 2 * x + 1;}
int no(int x) {return 2 * x;}int main(){std::ios::sync_with_stdio(false);std::cin.tie(nullptr);std::cout.tie(nullptr);int n;std::cin >> n;std::vector<int> a(n);TwoSat ts(2 * n + 2);fore(i, 0, n)	std::cin >> a[i];int tot= 2 * n - 1;std::map<std::pair<int, int>, int> pre;std::map<std::pair<int, int>, int> suf;ts.e[0].push_back(1);ts.e[2 * n - 1].push_back(2 * n - 2);fore(i, 0, n){if(i > 0)	ts.addedge(i - 1, 1, i, 1);if(i < n - 1)	ts.addedge(i, 1, i + 1, 1);if(i < n - 1){if(pre.find({a[i], a[i + 1]}) != pre.end()){ts.e[2 * i + 1].push_back(pre[{a[i], a[i + 1]}]);ts.e[tot + 1].push_back(pre[{a[i], a[i + 1]}]);}pre[{a[i], a[i + 1]}] = ++tot;ts.e[tot].push_back(2 * i);}}for(int i = n - 2; i >= 0; --i){if(suf.find({a[i], a[i + 1]}) != suf.end()){ts.e[2 * i + 1].push_back(suf[{a[i], a[i + 1]}]);ts.e[tot + 1].push_back(suf[{a[i], a[i + 1]}]);}suf[{a[i], a[i + 1]}] = ++tot;ts.e[tot].push_back(2 * i);}if(!ts.satisfiable(n)){std::cout << "NO\n";return 0;}auto v = ts.get_ans();std::vector<int> ans;fore(i, 0, n - 1)if(v[i])ans.push_back(i + 1);std::cout << ans.size() << endl;for(auto i : ans)	std::cout << i << ' ';std::cout << endl;return 0; 
}/*
https://pintia.cn/problem-sets/1705510247604809728/exam/problems/1705514248467492866?type=7&page=0
*/

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

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

相关文章

Android适配平板屏幕尺寸

一、划分手机和平板 人为判断方法: 大于6英寸的就是平板。小于6英寸的都是手机 平板尺寸&#xff1a; 6英寸、7英寸、10英寸、14英寸… Android系统支持多配置资源文件&#xff0c;我们可以追加新的资源目录到你的Android项目中。命名规范&#xff1a; 资源名字-限制符 l…

C++进阶03 模板与群体数据

听课笔记简单整理&#xff0c;供小伙伴们参考~&#x1f95d;&#x1f95d; 第1版&#xff1a;听课的记录代码~&#x1f9e9;&#x1f9e9; 编辑&#xff1a;梅头脑&#x1f338; 审核&#xff1a;文心一言 目录 &#x1f433;课程来源 &#x1f40b;模板 &#x1f40b;8.…

Vue2 —— 学习(六)

一、Vue 脚手架 &#xff08;一&#xff09;介绍 Vue 脚手架是 Vue 官方提供的标准化开发工具 &#xff08;开发平台&#xff09; 脚手架版本最新版本 是 4.x 文档可以查看 http://cli.vuejs.org/zh/ 就是vue 官网文档中 的 vue.cli command line interface &#xff08;…

Python 爬虫基础——http请求和http响应

写本篇文章&#xff0c;我认为是能把自己所理解的内容分享出来&#xff0c;说不定就有和我一样有这样思维的共同者&#xff0c;希望本篇文章能帮助大家&#xff01;✨✨ 文章目录 一、 &#x1f308;python介绍和分析二、 &#x1f308;http请求三、 &#x1f308;http响应四、…

Python项目2 数据可视化

生成数据 数据可视化 指的是通过可视化表示来探索数据&#xff0c;它与数据挖掘 数据挖掘 紧密相关&#xff0c;而数据挖掘指的是使用代码来探索数据集的规律和关联。数据集可以是用一行代码就能表 示的小型数字列表&#xff0c;也可以是数以吉字节的数据。 漂亮地呈现数据关…

【论文笔记】Planning-oriented Autonomous Driving

原文链接&#xff1a;https://arxiv.org/abs/2212.10156 1. 引言 目前的自动驾驶工业界通常为不同任务部署不同的模型&#xff0c;但优化的孤立性会导致模块之间的信息损失、误差积累和特征不对齐。 一种更好的设计是将各种任务整合为多任务学习&#xff0c;即为共享的特征提…

设计模式之责任链模式讲解

概念&#xff1a;使多个对象都有机会处理请求&#xff0c;从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条链&#xff0c;并沿着这条链传递该请求&#xff0c;直到有对象处理它为止。最匹配的场景应该就是逐层审批的模式。 责任链模式只有两个角色&#xff…

wife_wife-攻防世界

题目 注册发现可以注册管理员,但是好像有条件 抓包试试 没思路了 看看其他师傅的wp&#xff0c;用到 js 原型链污染攻击 Nodejs原型链污染攻击基础知识 | Savants Blog (lxscloud.top) 网站后端是Node.js搭建的 原型链污染 简单来讲&#xff0c;通过 newUser.__proto__ …

RHCE实验2-DNS服务正反向解析

实验开始 一、DNS正向解析 注&#xff1a; server端&#xff1a;192.168.32.147 node端&#xff1a;192.168.32.141 网址&#xff1a;www.openlab.com 1、server端和node端都关闭安全软件&#xff08;以server端为例&#xff09; [rootserver ~]# setenforce 0 [rootser…

Java基于微信小程序的校园跑腿小程序,附源码

博主介绍&#xff1a;✌程序员徐师兄、8年大厂程序员经历。全网粉丝15w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

vue3+element plus图片预览点击按钮直接显示图片的预览形式

1 需求 直接上需求&#xff1a; 我想要直接点击下面这个“预览”按钮&#xff0c;然后呈现出预览图片的形式 ok&#xff0c;需求知道了&#xff0c;下面让我们来看看如何实现吧 ~ 2 实现 template部分 <el-buttontype"primary"size"small"click&qu…

链表中常见的使用方法逻辑整理

文章目录 1. 链表特点2. 链表创建3. 链表遍历通用方法3.1 在链表的开头添加元素3.2 在链表的结尾添加元素3.3 删除链表的第一个元素3.4 删除链表的最后一个元素3.5 遍历链表3.6 查找链表中的元素3.7 反转链表 4. 常见面试题4.1 相交链表4.2 反转链表4.3 环形链表4.4 环形链表 I…

easyui combobox下拉框组件输入检索全模糊查询

前引&#xff1a; easyui下拉组件&#xff08;combobox&#xff09;&#xff0c;输入检索下拉内容&#xff0c;是默认的右模糊匹配&#xff0c;而且不支持选择。因业务要求需要做成全模糊查询&#xff0c;目前网上搜索有两种方案&#xff1a; 1.修改easyui源码&#xff0c;这个…

LeetCode700:二叉搜索树中的搜索

题目描述 给定二叉搜索树&#xff08;BST&#xff09;的根节点 root 和一个整数值 val。 你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在&#xff0c;则返回 null 。 代码 递归法 class Solution { public:TreeNode* searchBST(TreeN…

Visual Studio code无法正常执行Executing task: pnpm run docs:dev

最近尝试调试一个开源的项目&#xff0c;发现cmd可以正常启动&#xff0c;但是在vs中会报错&#xff0c;报错内容如下 Executing task: pnpm run docs:dev pnpm : 无法加载文件 E:\XXXX\pnpm.ps1&#xff0c;因为在此系统上禁止运行脚本。有关详细信息&#xff0c;请参阅 http…

组合导航的结果分段跳变问题

1 现象 用上海代数律动公司的AlgoT1-3组合导航设备采集数据进行组合导航算法调试&#xff0c;AlgoT1-3机器输出的结果很好很平滑&#xff0c;AlgoT1-3是带GNSS/INS的组合导航设备&#xff0c;另外还有一款更贵一点的带视觉的组合导航AlgoT1&#xff0c;效果会更好一些&#xf…

【Tars-go】腾讯微服务框架学习使用03-- TarsUp协议

3 TarsUP协议 统一通信协议 TarsTup | TarsDocs (tarscloud.github.io) TarsDocs/base at master TarsCloud/TarsDocs (github.com) &#xff1a; 有关于tars的所有介绍 每一个rpc调用双方都约定一套数据序列化协议&#xff0c;gprc用的是protobuff&#xff0c;tarsgo是统一…

每日OJ题_01背包③_力扣494. 目标和(dp+滚动数组优化)

目录 力扣494. 目标和 问题解析 解析代码 滚动数组优化代码 力扣494. 目标和 494. 目标和 难度 中等 给你一个非负整数数组 nums 和一个整数 target 。 向数组中的每个整数前添加 或 - &#xff0c;然后串联起所有整数&#xff0c;可以构造一个 表达式 &#xff1a; …

ThreadX:怎么确定一个线程应该开多少内存

ThreadX&#xff1a;如何确定线程的大小 在实时操作系统&#xff08;RTOS&#xff09;ThreadX中&#xff0c;线程的大小是一个重要的参数。这个参数决定了线程的堆栈大小&#xff0c;也就是线程可以使用的内存空间。那么&#xff0c;我们应该如何确定一个线程需要多大的字节呢…

C语言-----结构体详解

前面已经向大家介绍过一点结构体的知识了&#xff0c;这次我们再来深度了解一下结构体。结构体是能够方便表示一个物体具有多种属性的一种结构。物体的属性可以转换为结构体中的变量。 1.结构体类型的声明 1.1 结构体的声明 struct tag {member-list;//结构体成员变量 }vari…