第十五届吉林程序设计省赛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(树状数组,线性基)的主要内容,如果未能解决你的问题,请参考以下文章