• [洛谷P3857] [TJOI2008]彩灯


    P3857 [TJOI2008]彩灯

    n个灯,每个灯只有开关两种状态,开始都关着。

    m个开关,每个开关对应若干个灯,拉动一下就会使该开关控制的所有灯改变状态。

    问有多少种不同的状态。

    做法

    考虑把每个灯抽象成一个二进制位,开是1,关是0,那么当前状态就是一个二进制数。

    然后拉动开关就相当于给当前状态异或上一个数。

    于是问题转化为求一些数能xor出多少不同的数。(因为一开始是0,异或0等于不异或)

    考虑建立一个线性基。既然原序列xor能得到的集合与线性基xor能得到的集合相同,那么其大小也是相同的。

    由于线性基异或得到的数必定没有重复的(根据基的定义,有且仅有一种方式得到一个数),那么选或不选线性基里的一个数就会导致得到不同的数。

    而每个数有选和不选两种状态,所以答案是(2^{size})(size)是线性基内元素个数,即线性基大小)

    注意溢出。

    #include <iostream>
    using namespace std;
    char read()
    {
        char c;
        do
        {
            c = getchar();
        } while (c == ' ' || c == '
    ' || c == '
    ');
        return c;
    }
    typedef long long type;
    const int W = 51;
    type basis[W + 1];
    int siz;
    void ins(type x)
    {
        for (int i = W; i >= 1; i--)
        {
            if (x >> (i - 1))
            {
                if (basis[i] == 0)
                {
                    basis[i] = x;
                    siz++;
                    return;
                }
                x ^= basis[i];
            }
        }
    }
    int w, n;
    int main()
    {
        cin >> w >> n;
        for (int i = 1; i <= n; i++)
        {
            type x = 0;
            for (int j = 1; j <= w; j++)
            {
                char c;
                c = read();
                if (c == 'O')
                    x += 1ll << (j - 1);
            }
            ins(x);
        }
        cout << (1ll << siz) % 2008 << endl;
    }
    
  • 相关阅读:
    MongoDB
    前端框架之vue初步学习
    mysql再回首
    oracle之回顾二
    oracle再回首
    springboot之对之前的补充
    springCloud学习
    springboot-ssm的pom.xml
    MyCat
    11.Java反射机制 哦对了,前面的序号来自随笔关于编程之路的思索第一篇
  • 原文地址:https://www.cnblogs.com/water-lift/p/11166484.html
Copyright © 2020-2023  润新知