zoukankan      html  css  js  c++  java
  • [CQOI2013]新Nim游戏

    传送门

    首先,我们可以发现,只要在第一次我们自己拿的时候,使得对方无论怎么拿都不能使异或和为0即可获胜。 考虑到线性基任意一个非空子集的异或和不为0,那么我们只要给对方留下一个线性基即可。所以先手必胜。

    之后考虑怎么让代价最小。这个也很简单,我们仿照上一道题目的做法,优先插入权值大的堆。每次判断一下这个是否会被线性基异或出来,如果能的话,那么就要选取他。

    看一下代码。

    #include <bits/stdc++.h>
    #define rep(i,a,n) for(int i = a;i <= n;i++)
    #define per(i,n,a) for(int i = n;i >= a;i--)
    using namespace std;
    typedef long long ll;
    
    ll k,a[105],p[30],ans;
    
    bool pd(ll x)
    {
        ll b = x;
        per(i,60,0)
        {
            if((x ^ p[i]) < x) x ^= p[i];
            if(!x) {ans += b;return 1;}
        }
        return 0;
    }
    
    void insert(ll x)
    {
        per(i,60,0)
        {
            if(!((x >> i) & 1)) continue;
            if(!p[i]) {p[i] = x; break;}
            x ^= p[i];
        }
    }
    
    int main()
    {
        scanf("%lld",&k);
        rep(i,1,k) scanf("%lld",&a[i]);
        sort(a+1,a+1+k);
        per(i,k,1) if(!pd(a[i])) insert(a[i]);
        printf("%lld
    ",ans);
        return 0;
    }
    
    
  • 相关阅读:
    数据库期末考试复习
    函数 初识
    文件操作
    深浅copy 和 集合
    数据编码补充
    字典的增删改查和嵌套
    面试题 和 python 2与3的期区别
    英文练习
    初识数据类型
    测试基础-系统测试(2)
  • 原文地址:https://www.cnblogs.com/captain1/p/10211435.html
Copyright © 2011-2022 走看看