LOJ#6040. 「雅礼集训 2017 Day5」矩阵

news/2024/7/7 15:54:15

传送门

题解:
我们考虑一组 ABC(mod2) A ∗ B ≡ C ( mod 2 ) 的一组合法解中 A,C A , C 的关系。

首先 C C 的列向量一定在A的列向量所组成的线性空间里(根据矩阵乘法的过程)。

具体,我们设 A A 的秩为x,那么合法 B B 的个数就有(2nx)n个(因为每一列对应一个异或方程组,自由变量都有 nx n − x 个)。

现在我们要统计“秩为 x x 且列向量的线性空间包含C的合法 A A 的个数”。 发现不是很好做,我们可以稍加转化,变为:有序对(A,C),满足 A A 列向量的线性空间包含C,且 C C 的秩为r, A A 的秩为x,这样一对的贡献为 (2nx)n ( 2 n − x ) n ,求贡献和。 因为 C C 的秩一样的矩阵是等价的,最后只需要除以秩为r C C 的个数即可得到答案。

fi,j表示 in i ∗ n 的矩阵,秩为 j j 的方案数,容易发现确定了一个秩为x的矩阵 A A ,那么C的个数就是 fx,r f x , r 。 因为 A A 也只跟秩有关,那么我们枚举A的秩,贡献和即为 ni=rfn,ifi,r(2ni)n ∑ i = r n f n , i f i , r ( 2 n − i ) n f f 的DP很简单,时间复杂度:O(n2+n332)

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;

const int RLEN=1<<18|1;
inline char nc() {
    static char ibuf[RLEN],*ib,*ob;
    (ib==ob) && (ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
    return (ib==ob) ? -1 : *ib++;
}
inline int rd() {
    char ch=nc(); int i=0,f=1;
    while(!isdigit(ch)) {if(ch=='-')f=-1; ch=nc();}
    while(isdigit(ch)) {i=(i<<1)+(i<<3)+ch-'0'; ch=nc();}
    return i*f; 
}

const int N=2e3+50,mod=1e9+7;
inline int add(int x,int y) {return (x+y>=mod) ? (x+y-mod) : (x+y);}
inline int dec(int x,int y) {return (x-y<0) ? (x-y+mod) : (x-y);}
inline int mul(int x,int y) {return (LL)x*y%mod;}
inline int power(int a,int b,int rs=1) {for(;b;b>>=1,a=mul(a,a)) if(b&1) rs=mul(rs,a); return rs;}

int n,m,f[N][N],pw[N];
bitset <N> A[N];
int main() {
    n=rd(); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) A[i][j]=rd();
    int r=0;
    for(int i=1;i<=n;i++) {
        int p=r+1,l=p; 
        for(;l<=n && !A[l][i]; ++l); if(l>n) continue;
        if(l!=p) swap(A[l],A[p]);
        for(int j=p+1;j<=n;j++) if(A[j][i]) A[j]^=A[p];
        ++r;
    }
    pw[0]=1; for(int i=1;i<=n;i++) pw[i]=mul(pw[i-1],2);
    f[0][0]=1; for(int i=1;i<=n;i++) for(int j=0;j<=i;j++) f[i][j]=add((j?mul(f[i-1][j-1],dec(pw[n],pw[j-1])):0),mul(f[i-1][j],pw[j]));
    int ans=0; for(int x=r;x<=n;++x) ans=add(ans,mul(mul(f[n][x],f[x][r]),power(pw[n-x],n)));
    cout<<mul(ans,power(f[n][r],mod-2));
}

http://www.niftyadmin.cn/n/1725189.html

相关文章

Atcoder AGC004F : Namori

传送门 题解&#xff1a; 这种二分图反转相同颜色的第一反应就是先取个反。 然后我们考虑树的情况&#xff1a; 将树黑白染色&#xff0c;那么我们只能把颜色不同的相邻节点交换颜色。 其实这相当于把白点挪向黑点&#xff0c;然后原来的位置变为黑点。 显然白点和黑点的数…

什么是三层构架

三层架构(3-tier application) 通常意义上的三层架构就是将整个业务应用划分为&#xff1a;表现层&#xff08;UI&#xff09;、业务逻辑层&#xff08;BLL&#xff09;、数据访问层&#xff08;DAL&#xff09;。区分层次的目的即为了“高内聚&#xff0c;低耦合”的思想。 &a…

Atcoder AGC006D : Median Pyramid Hard

传送门 题解&#xff1a; 二分最终答案&#xff0c;然后转化为0,1串。 发现连续的0,1串每次往左右扩展1&#xff0c;那么我们找到距离中点最近的即可。 #include <bits/stdc.h> using namespace std;const int RLEN1<<18|1; inline char nc() {static char ibu…

LOJ#6436. 「PKUSC2018」神仙的游戏

传送门 题解: 瞎JB猜了个结论居然是对的&#xff0c;看了题解知道为什么对了。 我们考虑先做模糊串匹配&#xff0c;那么长度不大于n2n2的串只需要匹配上就行了。 否则我们判断他的每一个周期子串是否能作前缀即可。 原因是如果有非法的必然是&#xff1a;0→?→?→10→?…

如何使用TabControl控件?

1 如何用代码切换TabControl中的TabPage? 为按钮添加代码&#xff1a; TabControl1.SelectedIndex 1 其中1是TabPage2的索引 private void button1_Click(object sender, EventArgs e){tabControl1.SelectedIndex 1;} 2 如何隐藏TabControl中的TabPage标签&#x…

雅礼集训6.25 : gift (DP)

题意&#xff1a; (n≤2000)(n≤2000)题解&#xff1a; 好神啊。 首先考虑如果序列已知怎么做&#xff0c;我们把(ai,bi)(ai,bi)看做图中的边&#xff0c;那么形成若干环&#xff0c;答案就是 n−环数n−环数。 考虑如果不已知&#xff0c;那么已经有的边肯定形成若干条链…

DataGridView动态的绑定数据

下面的示例将说明如何获取一些数据&#xff0c;并在DataGridView控件中显示&#xff0c;为此&#xff0c;建立一个新的应用程序DisplayTabularData&#xff0c;如图32-1所示。 图http://new.51cto.com/files/uploadimg/20081127/090210168.jpg 这个简单的应用程序从Northwind数…

Atcoder AGC007C : Pushing Balls

传送门 题解&#xff1a; 把每个球的操作一次后的期望具体写出来&#xff0c;发现还是一个等差数列&#xff0c;猜个结论&#xff1a;把之后的局面用这个等差数列算是等价的&#xff08;其实应该也不难理解&#xff09;。 假设现在等差数列为(d,x)(d,x)(d,x)&#xff0c;我们…