题面

传送门

题解

我对线代一无所知

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

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

首先,关于\(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. python startswith与endswith

    如果你要用python匹配字符串的开头或末尾是否包含一个字符串,就可以用startswith,和endswith比如:content = 'ilovepython'如果字符串content以ilove ...

  2. PowerDesigner中CDM和PDM如何定义外键关系

    有A.B两张表(实体),各自有id作为主键,两表是一一对应关系.但略有不同: A表一条记录可以对应0或1条B表记录,B表一条记录必须对应唯一条A表记录. 这样的关系如何在CDM或PDM中定义? 在最后 ...

  3. scrapy-redis源码抛析

    #scrapy-redis--->queue.py-->class FifoQueue 队列 LifoQueue(lastinfirstout栈) #self.server父类Base中链 ...

  4. 11-24网页基础--Js基础语法

    1.运算符 比较运算符(7种):==/===/!=/>/</<=/>= ===(全等于) 2.字符串substring的用法 3.练习题:累加求和(运用Js的方法) 4.进制转 ...

  5. 问题:oracle 不等于;结果:Oracle中的不等于号

    Oracle中的不等于号 今天碰到一个Oracle不等于的问题,最后搜索了一下,发现下面资料,拿来跟大家分享一下   关于Oracle中的不等于号: 在Oracle中, <> != ~= ...

  6. LNMP 1.3 测试php解析

    测试解析LNMP的php解析 先打开nginx的配置文件 vim /usr/local/nginx/conf/nginx.conf location ~ \.php$ { root html; fas ...

  7. php二维数组排序方法(array_multisort,usort)

    一维数组排序可以使用asort.ksort等一些方法进程排序,相对来说比较简单.二维数组的排序怎么实现呢?使用array_multisort和usort可以实现 例如像下面的数组: $users = ...

  8. 恢复oracle的回收站的所有的表

    使用sys as sysdba 进入到sqlplus的控制界面 sqlplus / as sysdba 执行相关的命令,自动生成一个脚本文件 spool d:/a.sql select 'flashb ...

  9. oracle创建完实例删除的时候报ORA-01031:insufficient privileges错误,解决办法

    创建了一个数据库,想删除确报了一个ORA-01031:insufficient privileges错误 查了好久,总算解决了,原因是我的电脑登录账户不在ORA_DBA系统群组中,添加进去完美删除! ...

  10. php学习笔记-定义数组和引用数组元素

    上图包含两种定义数组的方法,一种是通过数组索引来创建的,一种是通过array()函数来创建的.