洛谷P3857 [TJOI2008]彩燈(線性基)
阿新 • • 發佈:2018-06-17
兩個 -- include tchar 輸出 long long 線性基 open 告訴
題目描述
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。
要是不知道這題是線性基的話可能要想很久,。。
但是知道了線性基這題就比較zz了,就是求個最大線性無關組,直接輸出pow(2,線性基的大小)
// luogu-judger-enable-o2 #include<cstdio> #include<cstring> #include<algorithm> #define LL long long using namespace std; const int MAXN = 1e5 + 10, B = 62, mod = 2008; inline int read() { char c = getchar(); int x = 0, f = 1; while(c < ‘0‘ || c > ‘9‘) {if(c == ‘-‘) f = -1; c = getchar();} while(c >= ‘0‘ && c <= ‘9‘) x = x * 10 + c - ‘0‘, c = getchar(); return x * f; } int N, M; char s[MAXN]; LL P[MAXN]; void Insert(LL x) { for(int i = B; i >= 0; i--) { if((x >> i) & 1) { if(!P[i]) {P[i] = x; return ;} x = x ^ P[i]; } } } main() { #ifdef WIN32 freopen("a.in", "r", stdin); #endif scanf("%d %d", &N, &M); for(int i = 1; i <= M; i++) { scanf("%s", s + 1); LL now = 0; for(int j = 1; j <= N; j++) if(s[j] == ‘X‘) now = now | (1ll << j - 1); // printf("%d\n", now); Insert(now); } int num = 0; for(int i = 0; i <= B; i++) if(P[i]) num++; printf("%lld", (1ll << num) % mod ); }
洛谷P3857 [TJOI2008]彩燈(線性基)