• hdu 3915 高斯消元


    http://acm.hdu.edu.cn/showproblem.php?pid=3915

    这道题目是和博弈论挂钩的高斯消元。本题涉及的博弈是nim博弈,结论是:当先手处于奇异局势时(几堆石子数相互异或为0),其必败。

    思路在这里,最后由于自由变元能取1、0两种状态,所以,最终答案是2^k,k表示自由变元的个数。

    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <string>
    #include <queue>
    #include <map>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    #define RD(x) scanf("%d",&x)
    #define RD2(x,y) scanf("%d%d",&x,&y)
    #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
    #define clr0(x) memset(x,0,sizeof(x))
    #define clr1(x) memset(x,-1,sizeof(x))
    #define eps 1e-9
    const double pi = acos(-1.0);
    typedef long long LL;
    typedef unsigned long long ULL;
    const int modo = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    const int inf = 0x3fffffff;
    const LL _inf = 1e18;
    const int maxn = 1005,maxm = 10005;
    
    #define MAXN 110
    #define MOD 1000007
    #define weishu 31
    LL a[MAXN], g[MAXN][MAXN];
    int Gauss(int n) {
        int i, j, r, c, cnt;
        for (c = cnt = 0; c < n; c++) {
            for (r = cnt; r < weishu; r++) {
                if (g[r][c])
                    break;
            }
            if (r < weishu) {
                if (r != cnt) {
                    for (i = 0; i < n; i++)
                        swap(g[r][i], g[cnt][i]);
                }
                for (i = cnt + 1; i < weishu; i++) {
                    if (g[i][c]) {
                        for (j = 0; j < n; j++)
                            g[i][j] ^= g[cnt][j];
                    }
                }
                cnt++;
            }
        }
        return n - cnt;
    }
    int main() {
        int c;
        int n, i, j;
        int ans, vary;
        scanf("%d", &c);
        while (c--) {
            int fuck = 0;
            scanf("%d", &n);
            for (i = 0; i < n; i++){
                scanf("%I64d", &a[i]);
                fuck ^= a[i];
            }
            for (i = 0; i < weishu; i++) {
                for (j = 0; j < n; j++)
                    g[i][j] = (a[j] >> i) & 1;
            }
            vary = Gauss(n);
            LL ans = 1;
            while(vary--){
                ans <<= 1;
                ans %= MOD;
            }
            printf("%I64d
    ",ans);
        }
        return 0;
    }
    


  • 相关阅读:
    【学习笔记/题解】树上启发式合并/CF600E Lomsat gelral
    【学习笔记/题解】虚树/[SDOI2011]消耗战
    【题解】 [GZOI2017]小z玩游戏
    【题解】CF1426E Rock, Paper, Scissors
    【题解】CF1426D Non-zero Segments
    【题解】NOIP2018 填数游戏
    【题解】NOIP2018 旅行
    【题解】NOIP2018 赛道修建
    【题解】时间复杂度
    【题解】「MCOI-02」Convex Hull 凸包
  • 原文地址:https://www.cnblogs.com/zibaohun/p/4074373.html
Copyright © 2020-2023  润新知