题目
试题编号 | 201512-5 |
---|---|
试题名称 | 矩阵 |
时间限制 | 1s |
内存限制 | 256MB |
问题描述 | |
输入输出 | |
样例 | |
规模 |
题目分析
乱解一通,本来想着根据题目去求A矩阵的逆应该是A的几次幂,但是没找到有效的办法去求,最后还是用暴力解的,只能得70分。
- 用bitset去存储计算很方便。
- 预先保存 A 2 , A 4 . . . A 2 29 A^2,A^4...A^{2^{29}} A2,A4...A229(最后三个规模的数据TLE)。然后矩阵快速幂。注意乘的顺序,和b矩阵乘的速度快得多。
C++代码(70分)
实在想不到最后三个点怎么过了。也没百度到满分解,后面再想吧!
#include <bits/stdc++.h>
#include <iostream>
#define rep(i,a,n) for(int i=a;i<n;i++)
using namespace std;
inline void in(int& x){
x=0;
int f=0;char ch=getchar();
for(;!isdigit(ch);ch=getchar()){f|=ch=='-';}
for(;isdigit(ch);ch=getchar()){x=(x<<3)+(x<<1)+(ch^48);}
if(f)x=-x;
}
const int M = 1000;
char t;
bitset<M>b;
bitset<M>ans;
bitset<M>tmp;
bitset<M>mz[31][M];
bitset<M>col[31][M];
int n,m,c,index;
void cal(int id){
rep(i,0,m){
if((mz[id][i]&ans).count()&1)tmp[i]=1;
else tmp[i] = 0;
}
ans = tmp;
}
inline void quick(int k){
index = 0;
while(k){
if(k&1)cal(index);
index++;
k>>=1;
}
}
inline void init(int x){
rep(d,1,x){
rep(i,0,m){
rep(j,0,m){
if(((mz[d-1][i]&col[d-1][j]).count()&1))mz[d][i][j] = 1,col[d][j][i] = 1;
}
}
}
}
int main(){
in(m);
rep(i,0,m){
rep(j,0,m){
if(getchar()=='1')mz[0][i][j]=1,col[0][j][i]=1;
}
getchar();
}
init(30);
rep(i,0,m){if(getchar()=='1')b[i]=1;}
in(n);
while(n--){
in(c);
ans = b;
index = 0;
while(c){
if(c&1)cal(index);
index++;
c>>=1;
}
rep(i,0,m){
putchar(ans[i]+'0');
}
putchar('\n');
}
return 0;
}