P3857 [TJOI2008] 彩灯

P3857 [TJOI2008] 彩灯

题目描述

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

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

输入格式

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

输出格式

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

数据范围

对于 100% 的数据,NM 不超过 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 @   liuboom  阅读(2)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示