题面

传送门

题解

我对线代一无所知

如果下面有啥说错的地方请说出来省的我一辈子都搞不明白

如果你没看懂以下在讲什么不要紧,因为我也没看懂

首先,关于\(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;
}

uoj#453. 【集训队作业2018】围绕着我们的圆环(线性代数+递推)的更多相关文章

  1. uoj #450[集训队作业2018]复读机

    传送门 \(d=1\),那么任何时刻都可以\(k\)个复读机的一种,答案为\(k^n\) \(d>1\),可以枚举某个复读机的复读次数(必须是\(d\)的倍数),然后第\(i\)个复读时间为\( ...

  2. UOJ 422 [集训队作业2018] 小Z的礼物 min-max容斥 期望 轮廓线dp

    LINK:小Z的礼物 太精髓了 我重学了一遍min-max容斥 重写了一遍按位或才写这道题的. 还是期望多少时间可以全部集齐. 相当于求出 \(E(max(S))\)表示最后一个出现的期望时间. 根据 ...

  3. UOJ #449. 【集训队作业2018】喂鸽子

    UOJ #449. [集训队作业2018]喂鸽子 小Z是养鸽子的人.一天,小Z给鸽子们喂玉米吃.一共有n只鸽子,小Z每秒会等概率选择一只鸽子并给他一粒玉米.一只鸽子饱了当且仅当它吃了的玉米粒数量\(≥ ...

  4. 【UOJ#450】【集训队作业2018】复读机(生成函数,单位根反演)

    [UOJ#450][集训队作业2018]复读机(生成函数,单位根反演) 题面 UOJ 题解 似乎是\(\mbox{Anson}\)爷的题. \(d=1\)的时候,随便怎么都行,答案就是\(k^n\). ...

  5. 【UOJ#422】【集训队作业2018】小Z的礼物(min-max容斥,轮廓线dp)

    [UOJ#422][集训队作业2018]小Z的礼物(min-max容斥,轮廓线dp) 题面 UOJ 题解 毒瘤xzy,怎么能搬这种题当做WC模拟题QwQ 一开始开错题了,根本就不会做. 后来发现是每次 ...

  6. UOJ#418. 【集训队作业2018】三角形

    #418. [集训队作业2018]三角形 和三角形没有关系 只要知道儿子放置的顺序,就可以直接模拟了 记录历史最大值 用一个pair(a,b):之后加上a个,期间最大值为增加b个 合并? A1+A2= ...

  7. UOJ#422. 【集训队作业2018】小Z的礼物

    #422. [集训队作业2018]小Z的礼物 min-max容斥 转化为每个集合最早被染色的期望时间 如果有x个选择可以染色,那么期望时间就是((n-1)*m+(m-1)*n))/x 但是x会变,中途 ...

  8. UOJ#428. 【集训队作业2018】普通的计数题

    #428. [集训队作业2018]普通的计数题 模型转化好题 所以变成统计有标号合法的树的个数. 合法限制: 1.根标号比子树都大 2.如果儿子全是叶子,数量B中有 3.如果存在一个儿子不是叶子,数量 ...

  9. uoj450 【集训队作业2018】复读机(生成函数,单位根反演)

    uoj450 [集训队作业2018]复读机(生成函数,单位根反演) uoj 题解时间 首先直接搞出单个复读机的生成函数 $ \sum\limits_{ i = 0 }^{ k } [ d | i ] ...

  10. [UOJ422][集训队作业2018]小Z的礼物——轮廓线DP+min-max容斥

    题目链接: [集训队作业2018]小Z的礼物 题目要求的就是最后一个喜欢的物品的期望得到时间. 根据$min-max$容斥可以知道$E(max(S))=\sum\limits_{T\subseteq ...

随机推荐

  1. (转)SC命令---安装、开启、配置、关闭windows服务 bat批处理

    本文转载自:http://blog.csdn.net/moruna/article/details/9190733 废话不多说,看命令行更直接! 一.直接使用cmd来进行服务的一些操作 1.安装服务 ...

  2. JDK 8 equals() & ==

    equals() 是 java.lang.Object 的一个实例方法,被所有的子类所继承(可被复写). 以下是 JDK 8 中 java.lang.Object.equals() 源码: publi ...

  3. 机器学习:SVM(非线性数据分类:SVM中使用多项式特征和核函数SVC)

    一.基础理解 数据:线性数据.非线性数据: 线性数据:线性相关.非线性相关:(非线性相关的数据不一定是非线性数据) 1)SVM 解决非线性数据分类的方法 方法一: 多项式思维:扩充原本的数据,制造新的 ...

  4. mjpg-streamer在Ubuntu下编译,运行

    1.将USB摄像头插上,查看是否找到设备,输入: wp@ubuntu:/home/$    ls   /dev/video* /dev/video0 2.安装必要的软件集: sudo apt-get ...

  5. rsync mac->windows openssh

    rsync -azvP --progress -e "ssh -p 6666" /Users/codar/360\344\272\221\347\233\230/ghld/ rsy ...

  6. openGL一些概念01

    顶点数据: 顶点数据是一系列顶点的集合. 一个顶点(Vertex)是一个3d坐标的数据的集合. 而顶点数据是用顶点属性(Vertex Attribute)表示的,它可以包含任何我们想用的数据. (但是 ...

  7. zookeeper 安装配置注意事项

    zoo.cfg 1.server.1/2/3  有几台配置几个 ​2.配置好hosts映射之后可以用node1替代IP地址 3.dataLogDir  下面配置的logs 的目录一定要创建 4.dat ...

  8. linux进程的软中断通信

    linux进程的软中断通信 要求 实现软中断通信的程序 使用系统调用fork()创建两个子进程,再用系统调用signal()让父进程捕捉键盘上发出的中断信号(即按delete键),当父进程接收到这两个 ...

  9. android 中context的具体作用和意义

    context在android中是非常重要的一个类,此类一般用于activity之中 从字面意思来看,这是环境变量,内部实现了一些方法,但是此类也可以看做是一个句柄,用来唯一标示activity 举个 ...

  10. 第2章 netty介绍与相关基础知识

    NIO有一个零拷贝的特性.Java的内存有分为堆和栈,以及还有字符串常量池等等.如果有一些数据需要从IO里面读取并且放到堆里面,中间其实会经过一些缓冲区.我们要去读,它会分成两个步骤,第一块它会把我们 ...