第十五届吉林程序设计省赛The 15th Jilin Provincial Collegiate Programming Contest I. Nim Game(树状数组,线性基)
Posted quinn18
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第十五届吉林程序设计省赛The 15th Jilin Provincial Collegiate Programming Contest I. Nim Game(树状数组,线性基)相关的知识,希望对你有一定的参考价值。
文章目录
题意
:
N
i
m
Nim
Nim 游戏,轮流从几堆石头中取出石头。在每一轮,玩家必须从一堆石头中取出一颗或多颗石头。不能拿石头的人输掉比赛。
戴安娜和爱娃可以每轮可以进行两个操作
o
p
=
=
1
op==1
op==1, 在一个区间内选出几堆进行
N
i
m
Nim
Nim 游戏,艾娃先手,戴安娜选牌堆,问戴安娜是否有机会胜利;
o
p
=
=
2
op==2
op==2, 给
[
l
,
r
]
[l,r]
[l,r] 的石头堆
a
[
i
]
a[i]
a[i] 加上
x
x
x 个石头。
题解
: N i m Nim Nim 博弈的结论是 所有 a [ i ] a[i] a[i]异或起来等于 0 0 0,先手必败。
所以
o
p
1
op1
op1 就是询问
a
[
l
.
.
.
r
]
a[l...r]
a[l...r] 内能否选出若干数使得异或为
0
0
0。
然后我们知道 线性基里面的任意一些数异或起来都不能得到 0 ,
那么问题最后转化为询问
[
l
,
r
]
[l,r]
[l,r] 的序列是否为线性基,是线性基那么先手必胜,戴安娜必败,假如不是线性基,那么就能找出任意一些数异或起来等于
0
0
0使得戴安娜胜。
o p 2 op2 op2 是区间操作可以用线段树或者树状数组差分
代码
:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e6+5;
int n;
int a[N];
int c[N],b[N];
int lowbit(int x)
return x&(-x);
void add(int i, int k)
while(i<=n)
c[i]+=k;
i+=lowbit(i);
int getsum(int i)
int res=0;
while(i>0)
res+=c[i];
i-=lowbit(i);
return res;
bool insert(int x)
for(int i=30; i>=0; i--)
if(x&(1<<i))
if(b[i]) x^=b[i];
else
b[i]=x;
return 0;
return 1;
signed main()
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int q;
cin>>n>>q;
for(int i=1; i<=n; i++)
cin>>a[i];
while(q--)
int op,l,r;
cin>>op>>l>>r;
if(op==1)
int x;
cin>>x;
add(l, x);
add(r+1, -x);
else
bool fl=0;
for(int i=0; i<=30; i++) b[i]=0;
for(int i=l; i<=r; i++)
if(insert(a[i]+getsum(i)))
fl=1;
break;//因为1e9范围最长的线性基为31,所以不会t
if(fl) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
return 0;
总结
Qaq
以上是关于第十五届吉林程序设计省赛The 15th Jilin Provincial Collegiate Programming Contest I. Nim Game(树状数组,线性基)的主要内容,如果未能解决你的问题,请参考以下文章
第十五届吉林省赛The 15th Jilin Provincial Collegiate Programming Contest C.Random Number Generator(数学 BSGS)
第十五届吉林省赛The 15th Jilin Provincial Collegiate Programming Contest C.Random Number Generator(数学 BSGS)