当前位置: 首页 > news >正文

2023NOIP A层联测21-异或

给定一长度为 N N N 的由非负整数组成的数组 a a a,你需要进行一系列操作,每次操作选择一个区间 [ l , r ] [l,r] [l,r],将 a [ l , r ] a_{[l,r]} a[l,r] 异或上 w w w。你需要将 a i a_i ai 全部变为 0 0 0

求最小操作次数。

N ≤ 17 N\le17 N17


考虑两个左端点相同的修改 [ l , r 1 ] , [ l , r 2 ] ( r 1 < r 2 ) [l,r_1],[l,r_2](r_1<r_2) [l,r1],[l,r2](r1<r2),可以把它拆成 [ l , r 1 ] [l,r_1] [l,r1] [ r 1 + 1 , r 2 ] [r_1+1,r_2] [r1+1,r2],次数相同。所以没有两个区间左端点相同,反过来右端点也不相同。

a a a 序列异或差分得到 b b b,其中 b i = a i ⊕ a i − 1 b_i=a_i\oplus a_{i-1} bi=aiai1,区间修改就变成双点修改(区间非后缀)或单点修改(区间为后缀)。最后同样要求 b b b 全为 0 0 0

N N N 个数抽象成 N N N 个点,修改就是在两个点之间连边(如果是单点修改,就是自环),一组方案由几个连通块组成。先暂时不管 w w w 的取值,考虑什么情况时会存在一个 w w w

一个连通块(大小为 x x x)中的边数只可能有两种情况, x − 1 x-1 x1(一棵树), x x x(一棵树加自环)。我们的目标是让最后连通块的数全为 0 0 0

考虑树的情况,发现有解当且仅当连通块内的数异或和为 0 0 0。下证之。

必要性:每次操作都是双点修改,整个连通块内的异或和不变,而最后要求异或和为 0 0 0,那么一开始也必须是 0 0 0

充分性:考虑把这些数按编号顺序排成一排,从前往后做操作,每次操作都把最前面的消掉了(变成 0 0 0),而最后应得到全 0 0 0 的序列,所以异或和必为 0 0 0

对于有自环的情况,自环的操作把那个点改成一个适当的值,让除去自环的这棵树的异或和为 0 0 0,所以这无论如何都有解。

发现答案就是 N N N 减去异或和为 0 0 0 的子序列个数。现在目标是最大化这样的子序列个数。

可以用状压 DP 求解,先枚举状态 i i i,再枚举它的子集 s s s,若 s s s 的异或和为 0 0 0 d p i ← max ⁡ ( d p i , d p i ⊕ s ) dp_i\gets\max(dp_i,dp_{i\oplus s}) dpimax(dpi,dpis)。时间复杂度 O ( 3 n ) O(3^n) O(3n)

注意要预处理出每个子集的异或和。

具体实现参照代码。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=(1<<17)+1;
int n,dp[N];
ll a[20],b[20],sum[N];
int main()
{freopen("xor.in","r",stdin);freopen("xor.out","w",stdout);scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%lld",&a[i]),b[i]=a[i]^a[i-1];int N=1<<n;for(int i=0;i<N;i++){for(int j=0;j<n;j++){if(i>>j&1){sum[i]^=b[j+1];}}}for(int i=0;i<N;i++){for(int s=i;s;s=(s-1)&i){if(!sum[s]) dp[i]=max(dp[i],dp[i^s]+1);}}printf("%d",n-dp[N-1]);
}
http://www.lryc.cn/news/212806.html

相关文章:

  • 分布式存储系统Ceph应用组件介绍
  • 【数据结构】数组和字符串(十一):字符串的定义与存储(顺序存储、链式存储及其C语言实现)
  • zk-Bench:SNARKs性能对比评估工具
  • 【Linux】NTP服务器配置、时间修改
  • 毕业设计基于SpringMVC+Mybatis+Bootstrap的电影院管理系统源码+数据库
  • vantUI(Tabbar标签页)浏览器返回上一页的失效问题
  • 【算法】Prim算法(求最小生成树)
  • go语言,yaml实现简单的workflow工作流
  • BaiduMallServcie
  • vue3+jsx+antd的插槽写法之一
  • Shell 学习之 if 命令
  • android 同步 服务器 时间
  • 10、电路综合-基于简化实频的宽带匹配电路设计方法
  • N-130基于springboot,vue校园社团管理系统
  • Syntax Error: TypeError: this.getOptions is not a function的解决(Vue)
  • 使用 kube-downscaler 降低Kubernetes集群成本
  • LeetCode热题100——哈希表
  • Kubeadm
  • 【Overload游戏引擎细节分析】PBR材质Shader---完结篇
  • C++设计模式_18_State 状态模式
  • 详解final, abstract, interface关键字
  • 统计特殊四元组
  • 腾讯云轻量应用服务器“镜像”怎么选择合适?
  • Ruby模块和程序组织
  • 14、SpringCloud -- WebSocket 实时通知用户
  • 智能井盖传感器推荐,万宾科技助力城市信息化建设
  • 3D模型格式转换工具HOOPS Exchange对工业级3D产品HOOPS的支持与应用
  • table 表体滚动, 表头、表尾固定
  • 第57篇-某钩招聘网站加密参数分析【2023-10-31】
  • C语言数据结构之数据结构入门