[传智杯 #5 初赛] I-不散的宴会

洛谷P8877 [传智杯 #5 初赛] I-不散的宴会

题目大意

学生社会可以被看作一个排列成等腰直角三角形的节点阵列。该节点阵列共有 n n n行,第 i i i行共有 i i i个节点,我们将第 i i i行第 j j j列的节点标号为 ( i , j ) (i,j) (i,j)

这些点具有权值。节点 ( i , j ) (i,j) (i,j)的权值为 r i ⊕ c j r_i\oplus c_j ricj,其中 r r r c c c是给定的 01 01 01序列。

这些点有边相连。对于 1 ≤ i < n 1\leq i<n 1i<n 1 ≤ j < i 1\leq j<i 1j<i,会有一条边连接 ( i , j ) (i,j) (i,j) ( i + 1 , j ) (i+1,j) (i+1,j)。此外,对于 2 ≤ i ≤ n 2\leq i\leq n 2in,还会有边连接 ( i , i ) (i,i) (i,i) ( i − 1 , a i ) (i-1,a_i) (i1,ai),其中 a a a是给定的序列。

现在你需要从这些节点中,选出一些节点,使得这些节点间两两不存在边相连,最大化选出来的节点的权值之和。

1 ≤ n ≤ 1 0 6 , 1 ≤ a i < i 1\leq n\leq 10^6,1\leq a_i<i 1n106,1ai<i


题解

首先,我们可以发现,这个图有 n ( n + 1 ) 2 \dfrac{n(n+1)}{2} 2n(n+1)个点, n ( n − 1 ) 2 + ( n − 1 ) \dfrac{n(n-1)}{2}+(n-1) 2n(n1)+(n1)条边,边数比点数少 1 1 1,这个图还是连通的,所以这个图是一棵树。

我们将所有第 1 1 1层的点、第 n n n层的点和度数为 3 3 3的点设为关键点。那么关键点的个数是 O ( n ) O(n) O(n)的,因为关键点只可能出现在第 1 1 1层、第 n n n层和连接 ( i , i ) (i,i) (i,i) ( i − 1 , a i ) (i-1,a_i) (i1,ai)的边上(可以自己画图感受一下)。

除了关键点,其他点的度数都为 2 2 2,那么这些点肯定都在一条链上。于是,我们可以把一条链看成两个关键点的边,这些关键点和边就构成一棵虚树,因为它的点的个数是 O ( n ) O(n) O(n)的,所以边的个数也是 O ( n ) O(n) O(n)的。

建虚树时,我们从下往上枚举每一行,用 v i v_i vi表示第 i i i列最后一个关键点在虚树上的编号。假设当前遍历到第 i i i行,则将 ( i − 1 , a i ) (i-1,a_i) (i1,ai) v a i v_{a_i} vai在虚树上连一条边,将 ( i , i ) (i,i) (i,i) ( i − 1 , a i ) (i-1,a_i) (i1,ai)在虚树上连一条边,并用 ( i − 1 , a i ) (i-1,a_i) (i1,ai)来更新 v a i v_{a_i} vai,还要求出新加在虚树上的点的权值。

建好的虚树后,即求树上最大点权独立集,可以用 D P DP DP来求。

f u , g u f_u,g_u fu,gu分别表示选择或不选择虚树上的节点 u u u的情况下,子树 u u u能取得的最大点权独立集的值。

假设有两个关键点 u u u v v v,它们之间通过链 s = { v 1 , v 2 , … , v k } s=\{v_1,v_2,\dots,v_k\} s={v1,v2,,vk}连接,则转移式为

f u + = max ⁡ { v a l ( v 2 , v 3 , … , v k − 1 ) + f v , v a l ( v 2 , v 3 , … , v k ) + g v } f_u+=\max\{val(v_2,v_3,\dots,v_{k-1})+f_v,val(v_2,v_3,\dots,v_k)+g_v\} fu+=max{val(v2,v3,,vk1)+fv,val(v2,v3,,vk)+gv}

g u + = max ⁡ { v a l ( v 1 , v 2 , … , v k − 1 ) + f v , v a l ( v 1 , v 2 , … , v k ) + g v } g_u+=\max\{val(v_1,v_2,\dots,v_{k-1})+f_v,val(v_1,v_2,\dots,v_k)+g_v\} gu+=max{val(v1,v2,,vk1)+fv,val(v1,v2,,vk)+gv}

其中 v a l ( v 1 , v 2 , … , v k ) val(v_1,v_2,\dots,v_k) val(v1,v2,,vk)表示 v 1 v_1 v1 v k v_k vk在不能选择相邻元素的情况下可以取得的最大点权独立集。

这个图还有一个性质:虚树中每条边在原图中对应的链上的点在同一列上。

那么,假设这条链在第 k k k列,其所在的区间为 [ a , b ] [a,b] [a,b],则:

  • c k = 0 c_k=0 ck=0,则每个位置的权值为 r a , r a + 1 … , r b r_a,r_{a+1}\dots,r_b ra,ra+1,rb
  • c k = 1 c_k=1 ck=1,则每个位置的权值为 ¬ r a , ¬ r a + 1 , … , ¬ r b \neg r_a,\neg r_{a+1},\dots,\neg r_b ¬ra,¬ra+1,,¬rb

那么,问题就转化为,查询对 r r r序列或 ¬ r \neg r ¬r序列求区间最大点独立集的大小。

对于一个 01 01 01序列,我们可以用贪心来求最大点独立集。比如,对于长度为 2 k 2k 2k的全 1 1 1段,最大点独立集显然为 k k k;对于长度为 2 k + 1 2k+1 2k+1的全 1 1 1段,最大点独立集显然为 k + 1 k+1 k+1。对于含有 0 0 0的序列,可以以 0 0 0作为分隔划分出各种全 1 1 1段,在分别求和相加即可。

下面,我们考虑如何求区间最大点独立集。

我们可以预处理出两个数组:

  • h i h_i hi表示仅考虑前 i i i个元素得出的最大点独立集的大小
  • p i p_i pi表示第 i i i个元素所在的全 1 1 1段的最后一个 1 1 1的位置。如果位置 i i i 0 0 0,则 p i = i − 1 p_i=i-1 pi=i1

假设我们当前要计算区间 [ l , r ] [l,r] [l,r]的最大点权独立集的大小,那么结果为

h r − h min ⁡ ( r , p l ) + ⌊ min ⁡ ( r , p l ) − l + 2 2 ⌋ h_r-h_{\min(r,p_l)}+\lfloor\dfrac{\min(r,p_l)-l+2}{2}\rfloor hrhmin(r,pl)+2min(r,pl)l+2

即先求出 [ min ⁡ ( r , p l ) + 1 , r ] [\min(r,p_l)+1,r] [min(r,pl)+1,r]这一段的最大点权独立集的大小,再统计 [ l , min ⁡ ( r , p l ) ] [l,\min(r,p_l)] [l,min(r,pl)]这一段长度为 r − min ⁡ ( r , p l ) + 1 r-\min(r,p_l)+1 rmin(r,pl)+1的全 1 1 1段的最大点权独立集大小(长度为 k k k的全 1 1 1段的最大点权独立集的大小为 ⌊ k + 1 2 ⌋ \lfloor\dfrac{k+1}{2}\rfloor 2k+1)。

时间复杂度为 O ( n ) O(n) O(n)

code

#include<bits/stdc++.h>
using namespace std;
const int N=1000000;
int n,cnt=0,R[N+5],C[N+5],a[N+5],v[N+5],vd[N+5],s[2*N+5],h[2][N+5],p[2][N+5];
int tot=0,d[2*N+5],l[2*N+5],r[2*N+5];
long long f[2*N+5],g[2*N+5],w[2*N+5][4];
long long gt(int i,int l,int r){if(r-l+1<=-2) return -1e18;if(l>r) return 0ll;int e=C[i];return 1ll*h[e][r]-h[e][min(r,p[e][l])]+(min(r,p[e][l])-l+2)/2;
}
void gtin(long long *v1,int i,int l,int r){v1[0]=gt(i,l,r);v1[1]=gt(i,l,r-1);v1[2]=gt(i,l+1,r);v1[3]=gt(i,l+1,r-1);
}
void add(int xx,int yy,int i,int ll,int rr){l[++tot]=r[xx];d[tot]=yy;r[xx]=tot;gtin(w[tot],i,ll,rr);
}
void init(int e){for(int i=1,lst=0;i<=n;i++){if((R[i]^e)==0){h[e][i]=h[e][i-1];lst=i;}else h[e][i]=h[e][lst]+(i-lst+1)/2;}p[e][n+1]=n;for(int i=n;i>=1;i--){if((R[i]^e)==0) p[e][i]=i-1;else p[e][i]=p[e][i+1];}
}
void dfs(int u){f[u]=s[u];for(int i=r[u];i;i=l[i]){int v=d[i];dfs(v);f[u]+=max(f[v]+w[i][3],g[v]+w[i][2]);g[u]+=max(f[v]+w[i][1],g[v]+w[i][0]);}
}
int main()
{scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%d",&R[i]);for(int i=1;i<=n;i++) scanf("%d",&C[i]);for(int i=2;i<=n;i++) scanf("%d",&a[i]);init(0);init(1);for(int i=1;i<=n;i++){v[i]=++cnt;vd[i]=n;s[cnt]=R[n]^C[i];}for(int i=n;i>=2;i--){add(++cnt,v[a[i]],a[i],i,vd[a[i]]-1);v[a[i]]=cnt;vd[a[i]]=i-1;s[cnt]=R[i-1]^C[a[i]];add(cnt,v[i],i,i,vd[i]-1);}dfs(cnt);printf("%lld",max(f[cnt],g[cnt]));return 0;
}

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

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

相关文章

正则表达式之学习笔记

正则表达式学习笔记 一、概念二、正则表达式组成三、常见的正则表达式3.1 .匹配任意字符3.2 * 匹配前一个字符的0个或多个实例3.3 ^ 匹配输入字符串的开头3.4 $ 匹配行尾3.5 [] 匹配字符集合\<\> 精确匹配符号 一、概念 正则表达式是由一系列特殊字符组成的字符串&#…

【笔试题】华为研发工程师编程题

1.汽水瓶 某商店规定&#xff1a;三个空汽水瓶可以换一瓶汽水&#xff0c;允许向老板借空汽水瓶&#xff08;但是必须要归还&#xff09;。 小张手上有n个空汽水瓶&#xff0c;她想知道自己最多可以喝到多少瓶汽水。 数据范围&#xff1a;输入的正整数满足 1≤n≤100 1≤n≤…

localforage-本地存储的优化方案

前言 前端本地化存储算是一个老生常谈的话题了&#xff0c;我们对于 cookies、Web Storage&#xff08;sessionStorage、localStorage&#xff09;的使用已经非常熟悉&#xff0c;在面试与实际操作之中也会经常遇到相关的问题&#xff0c;但这些本地化存储的方式还存在一些缺陷…

让uniGUI支持https

今天在专家的帮助下&#xff0c;成功的让uniGUI支持https了。 首先&#xff0c;去申请个**的证书。我同事去阿里申请的&#xff0c;申请回是一个zip文件&#xff0c;里面有两个文件&#xff0c;一个扩展是per&#xff0c;一个key 然后&#xff0c;把这两个证书文件放到uniGUI…

通过Chain Prompts方式将LLM的能力引入测试平台:正交实验测试用例生成

通过Chain Prompts方式将LLM的能力引入测试平台:正交实验测试用例生成 Chain Prompts Chain Prompts是指在一个对话或文本生成任务中,将前一个提示的输出作为下一个提示的输入,形成一个连续的链条。这种方法常常用于创建连贯的、有上下文关联的文本。在对话系统中,这种方…

微信小程序数据存储方式有哪些

在微信小程序中&#xff0c;数据存储方式有以下几种&#xff1a; 本地存储 本地存储是一种轻量级的数据存储方式&#xff0c;用于存储小量的数据&#xff0c;例如用户的配置信息、页面的状态等。微信小程序提供了 wx.setStorage() 和 wx.getStorage() 方法&#xff0c;用于将数…

【Java基础面试三十六】、遇到过异常吗,如何处理?

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 面试官&#xff1a;遇到过异常吗&#xff0…

reactnative 底部tab页面@react-navigation/bottom-tabs

使用react-navigation/native做的页面导航和tab‘ 官网&#xff1a;https://reactnavigation.org/docs/getting-started 效果图 安装 npm install react-navigation/nativenpm install react-navigation/bottom-tabs封装tabbar.js import { View, StyleSheet, Image } from …

C语言指针

指针 文章目录 指针1.指针概念2.指针变量2.1 定义指针变量2.2 引用指针变量2.3 指针变量作为函数参数 3.通过指针引用数组3.1数组元素的指针3.2 在引用数组元素时指针的运算3.3通过指针引用数组元素3.4用数组名作函数参数3.5 通过指针引用多维数组 4.通过指针引用字符串4.1字符…

vue 插槽 - 具名插槽

vue 插槽 - 具名插槽 **创建 工程&#xff1a; H:\java_work\java_springboot\vue_study ctrl按住不放 右键 悬着 powershell H:\java_work\java_springboot\js_study\Vue2_3入门到实战-配套资料\01-随堂代码素材\day05\准备代码\09-插槽-具名插槽 vue --version vue create…

Battery Charging Specification 1.2 中文详解

1. Introduction 1.1 Scope 规范定义了设备通过USB端口充电的检测、控制和报告机制,这些机制是USB2.0规范的扩展,用于专用 充电器(DCP)、主机(SDP)、hub(SDP)和CDP(大电流充电端口)对设备的充电和power up。这些机制适用 于兼容USB2.0的所有主机和外设。 1.2 Backgrou…

hugo-stack for github

静态博客框架jekyll、hexo和hugo三者之间的区别与差异 博客生成器? 全名为静态网站生成器&#xff0c; 可在任意拥有主机功能的环境下寄存(托管)可直接配合域名进行全球访问 劣势: 每次更新网页必须重新生成整个网站编译速度&#xff08;单位&#xff1a;秒&#xff09; Jek…

linux高频面试题目

01 如何使用单个命令行查看当前目录下的所有文件和子目录&#xff1f; ls -als -la 详细信息02 描述Linux中的文件权限系统。drwxr-xr–这种表示方式意味着什么&#xff1f; inux中的文件权限系统基于三种主要的实体&#xff1a;所有者&#xff08;owner&#xff09;、组&…

【Java基础面试三十九】、 finally是无条件执行的吗?

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 面试官&#xff1a; finally是无条件执行的…

【temu】分析拼多多跨境电商Temu数据分析数据采集

Temu是拼多多旗下跨境电商平台&#xff0c;于2022年9月1日在美国、加拿大、新加坡、中国台湾、中国香港等市场上线。本文作者从销售额、销量、产品分布等方面&#xff0c;对Temu产品进行了分析&#xff0c;一起来看一下吧。 item_get获得商品详情item_review获得商品评论列表it…

Leetcode—1726.同积元组【中等】

2023每日刷题&#xff08;六&#xff09; Leetcode—1726.同积元组 哈希表解题思路 实现代码 class Solution { public:int tupleSameProduct(vector<int>& nums) {unordered_map<int, int>count;int n nums.size();int i, j;for(i 0; i < n - 1; i) {f…

【MySQL】数据库数据类型

文章目录 1. 整体概要2. 数值类型(有符号) tinyint 创建表(无符号) tinyint 创建表bit类型float 类型(无符号)floatdecimal 3. 二进制类型char类型varchar类型 4. 日期时间日期时间类型 5. string 类型enum类型和set类型enum类型和set类型的查找在枚举中的查找在set中的查找 1.…

函数栈帧的创建和销毁

目录 引言&#xff1a; 1&#xff0c;函数栈帧的概念 2&#xff0c;函数栈帧的创建与销毁过程 2.1预备知识 2.2main函数栈帧的创建 2.2.1push ebp 2.2.2mov ebp,esp 2.2.3sub esp,0E4h 2.2.4push ebx &#xff1b;push esi&#xff1b;push edi 2…

【Windows】Edge浏览器自动更新服务启用选禁用被拒绝访问的解决方案

Windows系统的服务窗口里&#xff0c;把一些服务的启动类型选择禁用有可能会提示拒绝访问&#xff0c;怎么弄呢&#xff0c;这里讲一讲怎样禁用这个服务。 举一个类似禁用服务的例子&#xff1a;怎样关闭Edge浏览器的自动更新服务&#xff0c; 关闭服务 已知&#xff0c;Win…

[开发|数据库] postgresql数据默认数据为null导致排序排序失效

参考文献 默认为null的数据库字段导致SQL排序失效–以pg数据库为例 解决方案 在 PostgreSQL 中&#xff0c;如果你在排序操作中使用 NULL 值&#xff0c;并且希望将 NULL 值排在结果的最后&#xff0c;可以使用 ORDER BY … NULLS LAST 语法。如果你的排序中存在 NULL 值但排…