2019西北工业大学程序设计创新实践基地春季选拔赛(重现赛)-G(DP)
2019-04-08 23:26
211 查看
Chino with Train to the Rabbit Town
题目链接:https://ac.nowcoder.com/acm/contest/553/G
感谢大佬博客的指点:https://www.cnblogs.com/FrankChen831X/p/10666916.html
题意
给定n,k,(1<=n<=5e5)然后给出n个数ai(1<=ai<=1e5),问按顺序从1…n分组,最多能有多少个组的异或和为k。
输入描述:第一行是两个数n, k,接下来一行是n个数ai
输出描述:题目中要求的答案
示例:
输入:
3 1
1 2 3
输出:
2
思路
首先我们需要知道 a ^ b ^ b = a, 若有 a1 ^ a2 ^ a3 ^ a4 ^ a5 ^ k = a1 ^ a2 ^ a3,则有 a4 ^ a5 = k。
DP思路,我们可以用 DP[ i ] 表示到第 i 个人的时候最多有多少组的异或和为k,下面考虑状态转移方程,DP[ i ] 的取值有两种情况。第一种:当前 ai 无法与 ai 的前面若干个意愿值异或和为k,此时DP[ i ]=DP[ i -1 ]。第二种:当前 ai 可以与ai前若干个意愿值异或和为k,即存在 j <i , a(j+1) ^ a(j+2) ^ …^ a(i) =k,DP[ i ] =max(DP[ i - 1 ] ,DP[ j ] + 1 )。如何知道是否存在这个 j 呢?我们可以用sum记录ai的异或前缀和,然后设置一个pre数组记录各sum值对应的最后一个元素下标,这样pre[ sum^k ] 即为 j 。若不存在,pre数组为默认值-1,下面看代码。
AC代码
#include<bits/stdc++.h> using namespace std; typedef long long ll; #define MAXN 500005 int DP[MAXN],sum; int pre[MAXN]; int main() { std::ios::sync_with_stdio(false); int n,k; cin>>n>>k; memset(pre,-1,sizeof(pre)); pre[0]=0; for(int i=1;i<=n;++i){ int a; cin>>a; sum^=a; if(pre[sum^k]!=-1){ DP[i]=max(DP[i-1],DP[pre[sum^k]]+1); } else DP[i]=DP[i-1]; pre[sum]=i; } cout<<DP[n]<<endl; }
相关文章推荐
- 2019西北工业大学程序设计创新实践基地春季选拔赛(重现赛)补题笔记
- 2019西北工业大学程序设计创新实践基地春季选拔赛(重现赛)
- 2019西北工业大学程序设计创新实践基地春季选拔赛题解
- 【HDU5928 2016CCPC东北地区大学生程序设计竞赛 - 重现赛 G】【计算几何 凸包思想 枚举底点做DP】Birthday Gift 给定绳长最多围住多少个点
- hdu 5927 Auxiliary Set 2016CCPC东北地区大学生程序设计竞赛 - 重现赛 F题(树状dp)
- 2019知到app答案-创新工程实践 章节测试完整智慧树答案
- 《C语言及程序设计》实践参考——简单循环的流程图
- FJNU第二十届低年级程序设计竞赛(正式赛)-Problem C-汪老司机(简单DP)
- 《C语言及程序设计初步》_1.11算术运算符与算术表达式_实践13——坐标转换
- 2016春季练习——DP水题
- 程序设计基石与实践之C语言概述与特点
- uva fzu2019(数位dp)
- 《C语言及程序设计》实践项目——输出小星星
- 《C语言及程序设计》实践参考——另类求和
- Java实践(一)---程序设计概述
- 程序设计基石与实践系列之失落的C语言结构体封装艺术
- 【HDU5927 2016CCPC东北地区大学生程序设计竞赛 - 重现赛 F】【dfs序 + 线段树 or 树状数组 复杂度计算】Auxiliary Set 一个点如果是好点或是两个好点的LCA就是好
- 【HDU5932 2016CCPC东北地区大学生程序设计竞赛 - 重现赛 K】【树上背包 贪心乱搞】Backpack on Tree 物品成本只有12345下的树上背包
- Linux企业级项目实践之网络爬虫(6)——将程序设计成为守护进程
- 创新联盟实践项目