【洛谷P4706】取石子
Description
现在 Yopilla 和 yww 要开始玩游戏!
他们在一条直线上标记了 \(n\) 个点,从左往右依次标号为 \(1, 2, ..., n\) 。然后在每个点上放置一些棋子,其中第 \(i\) 个点放置了 \(a_i\) 个棋子。接下来,从 Yopilla 开始操作,双方轮流操作,谁不能操作谁输。每次的操作是:当前操作方选定一个有棋子的点 \(x\) ,然后选择至少一个点 \(x\) 上的棋子,然后把这些棋子全都移动到点 \(x / prime\) 上,其中 \(prime\) 是一个质数,且 \(prime \mid x\)
Yopilla 最初一次操作的策略是随机的:随机找到一个有棋子的点 \(x\) ,随机选择正整数个棋子 \(y\) ,随机转移到一个能转移到的点 \(z\) 。所有棋子可以看作是一样的,换句话说:两种操作不同,当且仅当三元组 \((x, y, z)\) 不同。之后双方都按照最优策略来操作。
Yopilla 想要预测,他能够获胜的概率是多少,答案对 \(998244353\) 取模。
Solution
我们发现,对于每一个数,如果以其幂指数之和为下标来将它们重新排列成一个数组,这个问题就变成了阶梯\(Nim\)问题。一次操作,相当于将一个数移动到其左边。不能移动者输。
事实上我们不需要实现这个重排操作。我们只需要知道每个数重排后是否在奇位置即可。
记输入数列为\(a\),我们统计出所有处于奇位置的数\(x\)的\(a_x\)的异或和\(sum\)。
我们要统计Yopilla一开始的随机操作一共有多少种可能、以及总共有多少种可能,使得操作后局面的先手必败。前者很好计算,就是\(\sum_x a_x*b_x\),其中\(b_x\)表示\(x\)这个数的不同质因子个数。
后者如何计算呢?对操作分类:(1)移动奇位置的数至偶位置、(2)移动偶位置的数至奇位置。
我们枚举所有奇位置的数。假设对该位置\(i\)操作后,总异或和\(sum\)等于0,即操作后先手必败,则\(a_i\)应该由\(a_i\)变成\(target=sum\; \text{xor}\; a_i\),
如果原值比目标值大,那么显然(1)容易满足,选出\(a_i-target\)个数,并将它们通过任意一个质因子移动到偶位置,一共有\(b_i\)种合法情况。
如果原值与目标值相等,则什么也做不了,一改就不满足要求,不作为合法情况考虑。
若原值小于目标值,则考虑(2),枚举所有能转移到\(i\)的偶位置\(j=i*p\)(其中\(p\)是枚举的质数),如果\(a_j \ge target-a_i\),那么合法情况就多了一种,因为\(j\)可以选\(target-a_i\)个数通过唯一一种方式——除去\(p\)——来到达\(i\)。
那么概率也就很好计算了。
Code
#include <cstdio>
using namespace std;
const int N=1000005,MOD=998244353;
int n,a[N];
bool vis[N];
int p[N],pcnt,b[N],c[N];
void sieve(){
int up=1e6;
for(int i=2;i<=up;i++){
if(!vis[i]){
p[++pcnt]=i;
b[i]=c[i]=1;
}
for(int j=1;j<=pcnt&&i*p[j]<=up;j++){
int x=i*p[j];
vis[x]=true;
c[x]=c[i]^1;
if(i%p[j]==0){
b[x]=b[i];
break;
}
b[x]=b[i]+1;
}
}
}
void readData(){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",a+i);
}
inline int fmi(int x,int y){
int res=1;
for(;y;x=1LL*x*x%MOD,y>>=1)
if(y&1) res=1LL*res*x%MOD;
return res;
}
void solve(){
int x=0;
for(int i=1;i<=n;i++)
if(c[i]) x^=a[i];
int legal=0;
for(int i=1;i<=n;i++)
if(c[i]){
int best=x^a[i];
if(best<a[i]) legal+=b[i];
else{
int delta=best-a[i];
if(!delta) continue;
for(int j=1;j<=pcnt&&i*p[j]<=n;j++)
if(a[i*p[j]]>=delta) legal++;
}
}
int all=0;
for(int i=1;i<=n;i++)
(all+=1LL*a[i]*b[i]%MOD)%=MOD;
int ans=1LL*legal*fmi(all,MOD-2)%MOD;
printf("%d\n",ans<0?ans+MOD:ans);
}
int main(){
sieve();
readData();
solve();
return 0;
}
【洛谷P4706】取石子的更多相关文章
- 洛谷 P4706 取石子 解题报告
P4706 取石子 题目描述 现在 Yopilla 和 yww 要开始玩游戏! 他们在一条直线上标记了 \(n\) 个点,从左往右依次标号为 \(1, 2, ..., n\) .然后在每个点上放置一些 ...
- 洛谷P2252 取石子游戏(威佐夫博弈)
题目背景 无 题目描述 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同数量的石子.最后 ...
- 洛谷——P2252 取石子游戏
P2252 取石子游戏 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同数量的石子.最后 ...
- 洛谷P1288 取数游戏II(博弈)
洛谷P1288 取数游戏II 先手必胜的条件需要满足如下中至少 \(1\) 条: 从初始位置向左走到第一个 \(0\) 的位置,经过边的数目为偶数(包含 \(0\) 这条边). 从初始位置向右走到第一 ...
- 洛谷P1880 [NOI1995]石子合并 纪中21日c组T4 2119. 【2016-12-30普及组模拟】环状石子归并
洛谷P1880 石子合并 纪中2119. 环状石子归并 洛谷传送门 题目描述1 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石 ...
- 洛谷 P1392 取数
题面 在做这道题前,先要会他的弱化版(实际一模一样,只是愚蠢的洛谷评测级别差了一档(睿智如姬无夜)) ----------------------------------弱化版------------ ...
- 洛谷P1288 取数游戏II[博弈论]
题目描述 有一个取数的游戏.初始时,给出一个环,环上的每条边上都有一个非负整数.这些整数中至少有一个0.然后,将一枚硬币放在环上的一个节点上.两个玩家就是以这个放硬币的节点为起点开始这个游戏,两人轮流 ...
- 洛谷P1288 取数游戏II
题目描述 有一个取数的游戏.初始时,给出一个环,环上的每条边上都有一个非负整数.这些整数中至少有一个0.然后,将一枚硬币放在环上的一个节点上.两个玩家就是以这个放硬币的节点为起点开始这个游戏,两人轮流 ...
- [洛谷P1880][NOI1995]石子合并
区间DP模板题 区间DP模板Code: ;len<=n;len++) { ;i<=*n-;i++) //区间左端点 { ; //区间右端点 for(int k=i;k<j;k++) ...
随机推荐
- Unity优化方向——优化Unity游戏中的垃圾回收(译)
介绍 当我们的游戏运行时,它使用内存来存储数据.当不再需要该数据时,存储该数据的内存将被释放,以便可以重用.垃圾是用来存储数据但不再使用的内存的术语.垃圾回收是该内存再次可用以进行重用的进程的名称. ...
- 【LeetCode算法题库】Day2:Median of Two Sorted Arrays & Longest Palindromic Substring & ZigZag Conversion
[Q4] There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of th ...
- Protocol buffer的使用案例
Protocolbuffer(以下简称PB)是google 的一种数据交换的格式,它独立于语言,独立于平台.google 提供了多种语言的实现:java.c#.c++.go 和 python,每一种实 ...
- Hyperledger Fabric(v1.2.0)代码分析1——channel创建
Hyperledger Fabric(v1.2.0)代码分析1--channel创建 0. e2e_cli Hyperledger Fabric提供了一个e2e的例子,该例中创建了一个基础的区块链网络 ...
- 工程能力之C4模型
概述 刚在InfoQ上看到一篇介绍C4Model的文章,觉得这个模型设计的很赞,很有指导意义,做个简单的记录. Why,为什么需要架构图? ThoughtWorks中国 文章中有几句话我觉得很有道理, ...
- 10.openldap备份与恢复
备份方式 一.使用slapcat指令备份 使用slapcat备份后的数据 经过相关无用条目处理,即可实现数据上的条目备份 备份指令如下 #备份 #slapcat -v -l openldap-back ...
- CentOS 6.7 安装配置 nagios
一.简介 Nagios是一款开源的免费网络监视工具,能有效监控Windows.Linux和Unix的主机状态,交换机路由器等网络设置,打印机等.在系统或服务状态异常时发出邮件或短信报警,第一时间 ...
- 查询数据库时mapper报错:It's likely that neither a Result Type nor a Result Map was specified.
因为mapper.xml里把resultType写成了parameterType
- Scrum Meeting 5 -2014.11.11
放假过掉一大半.大家都努力赶着进度,算法实现基本完成.可能还有些细小的改动,但也可以统一进入测试阶段了. 今天叫了部分在校人员开了个小会.任务决定以测试为主,同时开始进行服务器的部署. 在之前尝试服务 ...
- Teamwork#3,Week5,Scrum Meeting 11.20
到目前为止,第一轮迭代已经基本完成.由于时间问题,多店比较的高级功能要放到第二轮迭代实现. 大部分任务已经完成,在alpha版本发布之前我们剩余需要解决的问题有两个: 服务器.校园网服务器不能满足我们 ...