前言:

偶遇神秘博弈论,展现人类智慧,拼尽全力无法战胜。

题意:

给定一个长度为 \(n\) 的数列 \(a_i\),Alice和Bob手上分别有一个初始为0的数字(分别记为A,B)。Alice和Bob轮流做出如下操作:

从序列开头或结尾取出一个数 \(x\),让自己手上的数字异或上 \(x\),并把 \(x\) 从序列中删除。

令Alice为先手,Bob为后手,最后谁的数字大,谁就胜。如果先手与后手均采用最优策略,那么谁可以取胜?(或者平局,即两个人手上的数字一样大)

思路:

我们看到平局就非常的不舒服,考虑如何处理平局的情况,设所有数字的异或和为 \(s\),显然的,若最后是平局当且仅当 \(s=0\) ,于是接下来考 \(s\neq0\) 的情况。

因为操作是异或,考虑找到 \(s\) 的二进制最高位,记为 \(2^{pos}\),不难发现,先后手的胜负一定是在这一位上被区分的,同时,因为二进制数的按位操作是独立的,我们就可以把题目中的所有 \(a_i\) 都变成他们本身的二进制第 \(pos\) 位的数去考虑,于是问题就完全转化为:

\(0\leq a_i\leq1\),且一定有奇数个\(1\)的问题。

现在考虑手推几组样例,因为是和题目看起来是博弈论相关,我们考虑分 \(n\) 的奇偶进行讨论。可以发现,若 \(n\) 为偶数,由基本的奇偶性质,要么是所有下标为奇数的 \(a_i\) 上总共有奇数个\(1\),要么是所有下标为偶数的 \(a_i\) 上总共有奇数个\(1\),且两种情况不会同时成立。又注意到(惊人的注意力),先手可以随意控制后手选的下标的奇偶性,于是先手一定可以拿到奇数个\(1\),此时先手必胜。所以现在给出一个对整个解决问题都非常重要的结论:

当数组的长度为偶数,且内含奇数个1时,先手必胜。

为什么是用数组长度来描述这个结论,而不是 \(n\) 呢?且看下文。

现在考虑 \(n\) 为奇数的情况,考虑第一步,发现若两端都是\(0\),那么无论先手选哪一个,都会惊人的化归到上述结论,而此时是后手必胜。所以若两端至少存在一个\(1\),那么为了胜利,先手必须要选择\(1\),否则必败。

那么我们现在假定一开始两端至少存在一个\(1\),且Alice已经选了那个\(1\)。那么现在的情况就变成了数组长度为偶数且含有偶数个\(1\)的情况。

所以对于现在你发现,无论后手接下来选两端的\(0\)还是\(1\),先手都需要选择与后手一样的数字,否则又回到了最开始的那个结论,此时先手必败。那么我们采用贪心,先把两端相等的全部删掉,然后剩下的位置必须形如001111......(即相邻的奇数位置和偶数位置必须相等)先手才有可能胜利,否则后手一定必胜。

那么再更进一步确认先手胜利的条件,分析上述过程,我们令先手取了 \(x+1\) 次\(1\),而后手取了 \(x\) 次,也就是总共 \(2x+1\) 次,如果排除先手第一次选的\(1\),那么后面每个人分别就选了 \(x\) 个\(1\),若此时的 \(x\) 是一个奇数,则加上一开始的那一次,先手就得到了偶数个\(1\),败给后手。所以一开始记录序列中\(1\)的个数,如果:

\[cnt_1\equiv 1\pmod{4}
\]

且满足 \(n\) 为奇数时的最优策略分析,那么先手必胜,否则全是后手胜。

Code:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
inline int read() {
int x=0,f=1;char ch=getchar();
while(ch > '9' || ch < '0'){if(ch == '-'){f = -1;}ch = getchar();}
while(ch >= '0'&&ch <= '9'){x = x * 10 + ch - 48; ch = getchar();}
return x * f;
}
const int N = 1e5 + 10;
int n,a[N]; bool check(int l,int r)
{
while(a[l] == a[r]) ++l,--r;
if(l > r) return true;
for(int i = l;i <= r;i += 2)
{
if(a[i] != a[i + 1]) return false;
}
return true;
} int main()
{
int T;
T = read();
while(T--)
{
int s = 0;
n = read();
for(int i = 1;i <= n;++i)
{
a[i] = read();
s ^= a[i];
}
if(s == 0)
{
puts("Draw");
continue;
}
int pos = 30;
while(pos >= 0)
{
if(s >> pos & 1) break;
--pos;
}
s = 0;
for(int i = 1;i <= n;++i){
a[i] = a[i] >> pos & 1;
s += a[i];
}
if(n % 2 == 0) {
puts("Alice");
}else{
if(!a[1] && !a[n]) puts("Bob");
else if(s % 4 == 1){
if(a[1] && a[n])
{
if(check(2,n) || check(1,n - 1)) puts("Alice");
else puts("Bob");
}
else if(a[1])
{
if(check(2,n)) puts("Alice");
else puts("Bob");
}
else{
if(check(1,n - 1)) puts("Alice");
else puts("Bob");
}
}
else puts("Bob");
}
}
return 0;
}

2.25模拟赛T4题解的更多相关文章

  1. 【洛谷比赛】[LnOI2019]长脖子鹿省选模拟赛 T1 题解

    今天是[LnOI2019]长脖子鹿省选模拟赛的时间,小编表示考的不怎么样,改了半天也只会改第一题,那也先呈上题解吧. T1:P5248 [LnOI2019SP]快速多项式变换(FPT) 一看这题就很手 ...

  2. 2020.3.23 模拟赛游记 & 题解

    这次的模拟赛,实在是水. 数据水,\(\texttt{std}\) 水,出题人水,做题人也水.??? 游记就说一句: 水. T1 metro 弱智题. 人均 \(100pts\). #pragma G ...

  3. 20180606模拟赛T4——数学游戏

    数学游戏 题目描述: 小T又发脑残了,没错,她又要求奇怪的东西,这次她想知道[X,Y]之间整数有多少可以表示成K个不同的B的幂的和形势.如\(x,y,k,b=15,20,2,2\),则有: \[17= ...

  4. light题目讲解 7.25模拟赛T1

    心得:这一道题其实就是自己打暴力打出来的 没有想到正解真的就是暴力枚举 我的做法是这样的 就是枚举A字符串中长度为x的子串 看它是不是B串的子序列 接下来是我的绝望考试代码(100分AC) //lig ...

  5. 2017-9-10"切题如切菜杯"模拟赛T4 ZZI

    题目 YYH拿到了父亲给的钱欣喜若狂,把这些钱拿来造了n栋房子.现在他要给这些房子通电.他有两种方法:第一种是在房间里搭核电发电机发电,对于不同的房子,他需要花不同的代价Vi:,第二种是将有电的房子i ...

  6. 洛谷[LnOI2019]长脖子鹿省选模拟赛 简要题解

    传送门 听说比赛的时候T4T4T4标程锅了??? WTF换我时间我要写T3啊 于是在T4T4T4调半天无果的情况下260pts260pts260pts收场真的是tcltcltcl. T1 快速多项式变 ...

  7. 12.25模拟赛T1

    可以区间dp,但是复杂度太高. 所以应该是贪心,怎么贪心呢? 这种题目,最好还是手玩找一些规律. 可以发现,由于保证可以m次填完,所以颜色之间没有相互包含关系. 比较像分治的模型. 所以考虑拿到一个区 ...

  8. 20180610模拟赛T4——木棍

    有\(N\)根木棍,每根的长度\(L\)和重量\(W\)已知.这些木棍将被一台机器一根一根地加工.机器需要一些启动时间来做准备工作,启动时间与木棍被加工的具体情况有关.启动时间遵循以下规则: 加工第一 ...

  9. 2023 年 CCF 春季测试赛模拟赛 - 2 题解

    T1 约数和 标准解法 \(n = a_1^{b_1} \times a_2^{b_2} \dots a_k^{b_k}\) 那么根据算术基本定理的推广,约数个数和约数和都是可以快速计算得到 约数和 ...

  10. NOIP模拟赛10 题解

    t3: 题意 给你一棵树,然后每次两种操作:1.给一个节点染色 : 2. 查询一个节点与任意已染色节点 lca 的权值的最大值 分析 考虑一个节点被染色后的影响:令它的所有祖先节点(包括自身)的所有除 ...

随机推荐

  1. 猫映射(Arnold变换),猫脸变换介绍与基于例题脚本的爆破

    前置信息 http://www.jiamisoft.com/blog/index.php/7249-erzhituxiangjiamisuanfaarnold.html https://mp.weix ...

  2. RabbitMQ学习笔记【长更】

    文章发表在了我的博客上:https://blog.ysboke.cn/archives/64.html 一.MQ作用 就仨:异步.削峰.解耦 1.任务异步处理 将不需要同步处理的并且耗时长的操作由消息 ...

  3. L1-7、Prompt 的“调试技巧”

    ️ 一份 Prompt 没效果?不要急,调试它! 为什么要"调试 Prompt"? 就像写代码有 bug,Prompt 也可能"指令不清".当模型输出不理想时, ...

  4. Git 查看 tag 标签详解

    摘要:介绍git中tag标签的使用方法,包括创建标签.提交标签.查询标签和删除标签等. 我们拿到一个即将投产的标签后,需要确认标签是否打在了正确的分支,故需要查看标签的详情信息,保证顺利上线.基于此背 ...

  5. 构建基于Serverless架构的向量检索MCP Server

    构建基于Serverless架构的向量检索MCP Server 随着LLM与Agent的快速发展,向量检索成为构建高效语义搜索和智能推荐系统的关键技术之一.OpenSearch Service 作为一 ...

  6. 袋鼠云批流一体分布式同步引擎ChunJun(原FlinkX)的前世今生

    ​   一.前言 ChunJun(原FlinkX)是一个基于Flink提供易用.稳定.高效的批流统一的数据集成工具,是袋鼠云一站式大数据开发平台-数栈DTinsight的核心计算引擎,其技术架构基于实 ...

  7. ko在数栈中的应用

    ​ 引言 一项技术能得以广泛运用,其中的一个关键点在于工程化.前端从最开始的简单写写网页和样式,发展为需要处理复杂的逻辑,伴随而来的是问题是相关文件越来越多,简单在网页中引用已经解决不了问题,需要相关 ...

  8. ChunJun&OceanBase联合方案首次发布:构建一体化数据集成方案

    8月27日,ChunJun社区与OceanBase社区联合组织的开源线下Meetup成功举办,会上重磅发布了「OceanBase&ChunJun:构建一体化数据集成方案」. 这是OceanBa ...

  9. EDGE浏览器提示“无法安全下载……”

    EDGE浏览器升级后,下载文件时显示"无法安全下载 --"可以点击该下载后面的"-",再点击"保留",然后会弹出一个对话框,提示" ...

  10. C/C++将切片数据列表转换为二维数组形式

    Slice2Matrix 本文档将以切片数据为例介绍读入文本格式数据,并将一维属性值写为二维阵列的过程. 实际工区中的切片常常是不规则的,因此在将其转换为二维阵列的过程中,需将切片填充为一个规则的矩形 ...