P3857 [TJOI2008] 彩灯

P3857 [TJOI2008] 彩灯

题目描述

Peter 女朋友的生日快到了,他亲自设计了一组彩灯,想给女朋友一个惊喜。已知一组彩灯是由一排 \(N\) 个独立的灯泡构成的,并且有 \(M\) 个开关控制它们。从数学的角度看,这一排彩灯的任何一个彩灯只有亮与不亮两个状态,所以共有 \(2^N\) 个样式。由于技术上的问题,Peter 设计的每个开关控制的彩灯没有什么规律,当一个开关被按下的时候,它会把所有它控制的彩灯改变状态(即亮变成不亮,不亮变成亮)。假如告诉你他设计的每个开关所控制的彩灯范围,你能否帮他计算出这些彩灯有多少种样式可以展示给他的女朋友?

注: 开始时所有彩灯都是不亮的状态。

输入格式

每组测试数据第一行为两个整数 \(N\)\(M\),用空格隔开。紧接着是有 \(M\) 行,每行都是一个长度为 \(N\) 的字符串,表示一个开关控制彩灯的范围(\(N\) 盏灯),如果第 \(i\) 个字母是大写字母 O,则表示这个开关控制第 \(i\) 盏灯,如果第 \(i\) 个字母是大写字母 X,则表示这个开关不控制此灯。

输出格式

输出这些开关和彩灯可以变换出来的样式数目。由于这个值可能会很大,请求出它对于整数 \(2008\) 的余数。

数据范围

对于 \(100\%\) 的数据,\(N\)\(M\) 不超过 \(50\)

说句闲话

Starbucks 实在是有点吵,只能来写一下很久之前的解题报告了,突然发现我的解题报告系列里面竟然没有线性基?这是不好的(’へ’)。

Solution:

我们认为你已经学过了线性基,我们发现每一个开关其实就对应一个数字,然后我们只关心线性基上有多少个 \(base\) 不为0。注意,\(base\) 中不为0的个数,而不是其他任何东西。

答案就是2的\(base\) 中不为0的个数次方。

Code:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+5;
const int inf=70;
const int mod=2008;
struct Node {
	int y;
	bool operator <(const Node &n1)const{
		return y>n1.y;
	}
}e[N];
int n,m,ans;
int base[inf];
char c[inf];
void ins()
{
	int x=0;
	for(int i=1;i<=n;i++)
	{
		x<<=1;
		x+=(c[i]=='O');
	}
	for(int i=n;i>=0;i--)
	{
		if(x&(1ll<<i))
		{
			if(!base[i])
			{
				base[i]=x;
				ans++;
				break;
			}
			x^=base[i];
		}
	}
}
void work()
{
	//freopen("1.in","r",stdin);
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		scanf("%s",c+1);
		ins();
	}
	int sum=(1ll<<ans)%mod;
	printf("%lld",sum);
}	
#undef int
int main()
{
	work();
}
posted @ 2025-01-24 16:13  liuboom  阅读(9)  评论(0)    收藏  举报