【GDOI2022PJD1T2 数列游戏】题解
D1T2 数列游戏
题目
有一个长度为 的序列 。
如果序列的长度大于 1,那么你就能进行操作,每次操作可以选择两个相邻的数 合并,得到一个新的数 ⊕ (“⊕”表示异或),每次操作都会使序列的长度减少 1。例如对将序列 中的第 2个和第 3 个数进行合并,会得到新序列 ,并可以进行下一轮操作。
你需要进行若干次操作(可能是 0 次),使得最终序列任意子区间的异或和不为 0。子区间的定义为连续的一段数 。
求满足条件的最终序列的最长长度。
思路
记数列 的异或前缀和为 ,则区间 的异或和为 ⊕ 。
我们要使任意区间异或和不为0,就是要是 互不相同且皆大于0.
因此,我们要将不符合要求的 消除。
假如我们想要让某个 消除,我们只需要合并 和 即可。
但在程序实现的过程中,我们并不需要模拟消除,只需要统计多少个不同的即可。
无解的情况是整个数列异或和为0。
Code
#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'
){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x
<<3)+(ch^48);ch=getchar();}return x*f;}
//#define N
//#define M
//#define mo
int n, m, i, j, k, T;
map<int, int>mp;
signed main()
{
// freopen("tiaoshi.in", "r", stdin);
// freopen("tiaoshi.out", "w", stdout);
n=read(); mp[0]=1;
for(i=1; i<=n; ++i)
{
j=read(); k^=j;
if(!mp[k]) ++m, mp[k]=1;
}
printf("%lld", (k==0 ? -1 : m));
return 0;
}
总结
这道题在考场上没想出来,值得反思。
对于区间异或和的问题,可以多思考前缀异或和的思想。
而区间异或和为0的情况,就是存在前缀异或和相等。
以后对于区间异或的情况可以多往这个方面想。
本文来自博客园,作者:zhangtingxi,转载请注明原文链接:https://www.cnblogs.com/zhangtingxi/p/16179653.html
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战