首页 > 其他 > 详细

洛谷P3857 [TJOI2008]彩灯 [线性基]

时间:2018-07-18 22:35:07      阅读:184      评论:0      收藏:0      [点我收藏+]

  题目传送门

彩灯

题目描述

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

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

输入输出格式

输入格式:

 

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

 

输出格式:

 

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

 

输入输出样例

输入样例#1: 
2 3
OO
XO
OX
输出样例#1: 
4

说明

可见样例中第一个开关控制了所有的彩灯,而后两个开关分别控制了第一个和第二个彩灯,这样我们可以只用后两个开关控制彩灯,可以变换出来所有的22个状态。

30%的数据中,N和M不超过15。

70%的数据中,N和M不超过50。

 


  分析:

  很显然,控制器可以转换成一个二进制数,那么很不难想到用线性基了。

  但是这道题有个坑点,因为控制器控制的位置要么都亮要么都不亮,所以是不能分开控制的,那么求出线性基以后当然不能简单的异或,应该是每有一个基向量就让答案乘以2再加1。还有一种全部灯都不亮的情况,所以最后答案还要加1。(做出来这题后被读入卡了好久。。。)

  Code:

 

 1 //It is made by HolseLee on 18th July 2018
 2 //Luogu.org P3857
 3 #include<bits/stdc++.h>
 4 using namespace std;
 5 typedef long long ll;
 6 ll n,m,a[51],b[71],ans;
 7 int main()
 8 {
 9     scanf("%lld%lld",&n,&m);
10     char ch[71];
11     for(int i=1;i<=m;i++){
12         scanf("%s",ch);
13         for(int j=0;j<n;j++)
14         if(ch[j]==O)
15         a[i]^=(1LL<<j);}
16     for(int i=1;i<=m;i++)
17     for(int j=62;j>=0;j--){
18         if(!(a[i]>>j))continue;
19         if(!b[j]){b[j]=a[i];break;}
20         a[i]^=b[j];}
21     for(int j=62;j>=0;j--)
22     if(b[j])ans=ans*2+1;ans++;
23     printf("%lld",ans%2008);
24     return 0;
25 }

 

洛谷P3857 [TJOI2008]彩灯 [线性基]

原文:https://www.cnblogs.com/cytus/p/9332808.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!