题面
题解
我对线代一无所知
如果下面有啥说错的地方请说出来省的我一辈子都搞不明白
如果你没看懂以下在讲什么不要紧,因为我也没看懂
首先,关于\(A\times B \equiv C \pmod{2}\)的方程的一组合法解,\(C\)的列向量必定在\(A\)的列向量的线性空间里
那么\(B\)就可以看成一个方程组……
设\(A\)的秩为\(x\),那么\(B\)的合法的解的个数就是\((2^{q-x})^s\)
大概意思就是说因为\(A\)的秩只有\(x\),每一列对应一个异或方程组,有\(q-x\)个*元
我们需要统计\((A,C)\),其中\(C\)的列向量在\(A\)的列向量的线性空间中,且\(A\)的秩为\(x\),\(C\)的秩为\(r\),这一组的贡献要乘上一个\((2^{q-x})^s\)。然后发现所有秩为\(r\)的\(C\)是等价的,只要最后除以秩为\(r\)的\(C\)的个数就行了
所以要怎么数啊……我实在看不太懂啊……
设\(f_{i,j}\)表示\(p\times i\)的矩阵,秩为\(j\)的方案数,\(g_{i,j}\)表示\(i\times s\)的矩阵,秩为\(j\)的方案数,递推的方式比较简单,看代码应该能懂这里就不讲了
所以如果我们确定了\(A\)的秩\(x\),以及\(C\)的秩\(r\),那么\((A,C)\)的数量就为\(g_{x,r}\)(感性理解一下好了……)
所以如果我们确定了\(C\)的秩\(r\),答案就是\(\sum_{i=r}^q f_{q,i}g_{i,r}\)
对于每一个\(r\)记录答案就是了
然而这里需要我们动态维护矩阵\(C\)的秩诶?
大概就是一个线性基吧……把\(C\)给放进一个线性基里,每次修改一行的时候先删除。删除就是把线性基里所有包含这一行的元素删除这一行的贡献。如果某一个元素只有这一行,那么说明删去这一行之后矩阵的秩会减\(1\)
//minamoto
#include<bits/stdc++.h>
#define R register
#define ll long long
#define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){
R int res,f=1;R char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
return res*f;
}
inline int get(){R char ch;while((ch=getc())>'9'||ch<'0');return ch-'0';}
char sr[1<<21],z[25];int K=-1,Z=0;
inline void Ot(){fwrite(sr,1,K+1,stdout),K=-1;}
void print(R int x){
if(K>1<<20)Ot();if(x<0)sr[++K]='-',x=-x;
while(z[++Z]=x%10+48,x/=10);
while(sr[++K]=z[Z],--Z);sr[++K]='\n';
}
const int N=1005,P=1e9+7;
inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
int ksm(R int x,R ll y){
R int res=1;
for(;y;y>>=1,x=mul(x,x))if(y&1)res=mul(res,x);
return res;
}
bitset<N>a[N],b[N];int bin[N],id[N],pos[N],f[N][N],g[N][N],ans[N];
int p,q,s,m,k,las,r,n,res;
void ins(R int i){
fd(j,s,1)if(a[i][j]){
if(!id[j]){++r,id[j]=i,pos[i]=j;return;}
a[i]^=a[id[j]],b[i]^=b[id[j]];
}
pos[i]=0;
}
int erase(int i){
int mn=s+1,x=0;
fp(j,1,p)if(b[j][i]&&cmin(mn,pos[j]))x=j;
fp(j,1,p)if(b[j][i]&&j!=x)a[j]^=a[x],b[j]^=b[x];
if(pos[x])--r,id[pos[x]]=0,pos[x]=0;
a[x].reset(),b[x].reset();
return x;
}
void init(){
n=N-1;
bin[0]=1;fp(i,1,n)bin[i]=mul(bin[i-1],2);
f[0][0]=g[0][0]=1;
fp(i,1,n)fp(j,0,i){
f[i][j]=add((j?mul(f[i-1][j-1],dec(bin[p],bin[j-1])):0),mul(f[i-1][j],bin[j]));
g[i][j]=add((j?mul(g[i-1][j-1],dec(bin[s],bin[j-1])):0),mul(g[i-1][j],bin[j]));
}
for(R int i=1,S=bin[s];i<=n;++i)bin[i]=mul(bin[i-1],S);
fp(r,0,s){
res=0;
fp(i,r,q)res=add(res,1ll*f[q][i]*g[i][r]%P*bin[q-i]%P);
ans[r]=mul(res,ksm(g[p][r],P-2));
}
}
int main(){
// freopen("testdata.in","r",stdin);
p=read(),q=read(),s=read(),m=read(),k=get();
init();
fp(i,1,p){
fp(j,1,s)a[i][j]=get();
b[i][i]=1,ins(i);
}
print(las=ans[r]);
while(m--){
int j=read()^(las*k),x=erase(j);
fp(i,1,s)a[x][i]=get();
b[x][j]=1,ins(x),print(las=ans[r]);
}
return Ot(),0;
}