[Ybt Gold Medal Navigation 8-1-1] [luogu P3857] Lantern/Linear basic example

Lantern

Topic link: ybt gold medal navigation 8-1-1 / luogu P3857

General idea

There are some lights, and then some buttons.
A certain button can make some bulbs change on or off.
Then ask how many different states you can make in this row of lights.
(Different states: only need to have a different light bulb on and off.)

Ideas

When we first saw the title of this question, we would think of using state pressure dp to do it.
Just fi, j f_{i,j}fi,jRepresents the former iii buttons, the state of the light isjjDoes the situation of j exist?

But if you look at the data range, n ≤ 50 n\leq 50n. 5 0 , not like pressure.

Then you consider using other methods.
Then you press the button equivalent to XOR, what is XOR? XOR A binary number composed of lights that you can control.
Then you XOR numbers, you will think of using linear basis to do it.

What is the linear basis?
It is a set, and some of the numbers in the set can be XORed to get all the numbers in your original set.
Then no matter how it chooses, it will not XOR out 0 00

Then you will think that its number must be less than or equal to the number of your original set.
Then you consider how to construct this thing.
You can consider what changes will happen to the original linear basis every time you add one more number.
We first stipulate that fi f_ifiIs the most significant 1 1 in binary1 is theiiThe linear basis of the i position.

Then we try to insert a number, we enumerate each 1 1 in the binary of this number from high to low1 . Then if for the number of digits you foundiii , fruitfi = 0 f_i = 0fi=0 , that is, there is no number, then insert your current number. If there are numbers, then you start thinking about what to do.

Because you must have a way to construct this number, but you already have a number, even if you hard insert this number later, it will become 0 0 due to XOR.0 , it may cause the entire sequence to be0 00 .
Then you try to construct this number from the two numbers in the linear basis. Obviously, your current number is to be selected, and the other is the exclusive OR of your current number.
Then you can XOR your current number withfi f_ifi, And then continue to look for it.

It can be seen that this is feasible, and fi f_ifi only one.

Then after you construct the linear bases, you consider how many numbers can be constructed from these linear bases.
That is 2 k 2^k2k k k k is the size of the linear basis.

Code

#include<cstdio>
#define mo 2008
#define ll long long

using namespace std;

int n, m;
ll now, f[51], ans;
char c[101];

void add(ll x) {
    
    
	for (int i = n; i >= 1; i--) {
    
    
		if ((x >> i) & 1ll) {
    
    //从高到低位枚举这个数的 1(二进制中)
			if (!f[i]) {
    
    //线性基中是空的,就可以直接存入走人
				f[i] = x;
				return ;
			}
			else x ^= f[i];//不是空的,那如果非要用这个数,下面的就要它跟这个数异或的结果
			//因为你把它异或了,后面插这个,才能用异或的和它异或出你现在的数
		}
	}
}

int main() {
    
    
	scanf("%d %d", &n, &m);
	for (int i = 1; i <= m; i++) {
    
    
		scanf("%s", c + 1);
		
		now = 0;
		for (int j = 1; j <= n; j++)
			if (c[j] == 'O') now |= 1ll << j;//把它二进制对于的数还原出来
		
		add(now);//往线性基里面新放数
	}
	
	ans = 1;
	for (int i = 1; i <= n; i++)
		if (f[i])//统计哪一位可以选亮不亮
			ans = (ans << 1ll) % mo;//可以亮或者不亮
	
	printf("%lld", ans);
	
	return 0;
}

Guess you like

Origin blog.csdn.net/weixin_43346722/article/details/114084978