「2020-2021 集训队作业」Yet Another Linear Algebra Problem(行列式,Binet-Cauchy 公式)
题面
出题人:T
L
Y
\tt TLY
TLY 太阳神:Tiw_Air_OAO
「
2020
—
2021
集
训
队
作
业
」
Y
e
t
A
n
o
t
h
e
r
L
i
n
e
a
r
A
l
g
e
b
r
a
P
r
o
b
l
e
m
传
统
1000
m
s
512
M
i
B
{\tt「2020—2021~集训队作业」Yet~Another~Linear~Algebra~Problem}\\\\ {\tt_{传统~~~~~1000\,ms~~~~~512\,MiB}}
「2020—2021 集训队作业」Yet Another Linear Algebra Problem传统 1000ms 512MiB
题目描述
您需要解决两个独立(但类似)的子问题:
问题一:给定
n
n
n 个在
G
F
(
3
)
GF(3)
GF(3)(数字都模
3
3
3)上的
m
m
m 维向量,记它们张成的线性空间为
V
V
V。求从
n
n
n 个向量中选出一组向量,使得它们是
V
V
V 的基的方案数。对
3
3
3 取模。
问题二:给定
n
n
n 个在
G
F
(
2
)
GF(2)
GF(2) 上的
m
m
m 维向量,记它们张成的线性空间为
V
V
V。其中第
i
i
i 个向量有颜色
c
i
c_i
ci。求从每种颜色中恰好选出一个向量,使得它们是
V
V
V 的基的方案数。对
2
2
2 取模。
注:为了凸显主要矛盾而忽略次要矛盾,保证
V
V
V 的维数为
m
m
m。
输入格式
第一行包含一个正整数
t
a
s
k
i
d
taskid
taskid,表示需要解决的问题编号。
第二行包含两个正整数
n
,
m
n,m
n,m,含义见上。
接下来输入
n
n
n 行:
如果
t
a
s
k
i
d
=
1
taskid=1
taskid=1,则第
i
i
i 行包含
m
m
m 个非负整数
v
i
,
1
,
v
i
,
2
,
…
,
v
i
,
m
v_{i,1},v_{i,2},\ldots,v_{i,m}
vi,1,vi,2,…,vi,m,描述了第
i
i
i 个向量。
如果
t
a
s
k
i
d
=
2
taskid=2
taskid=2,则第
i
i
i 行包含
m
+
1
m+1
m+1 个非负整数
v
i
,
1
,
v
i
,
2
,
…
,
v
i
,
m
,
c
i
v_{i,1},v_{i,2},\ldots,v_{i,m},c_i
vi,1,vi,2,…,vi,m,ci,描述了第
i
i
i 个向量与它的颜色。
输出格式
输出一行一个正整数表示答案。
样例 1
输入
1
3 2
0 1
1 2
1 1
输出
0
样例 2
输入
1
4 3
1 1 0
1 2 0
1 2 2
1 1 1
输出
1
样例 3
输入
1
5 3
1 1 0
0 1 2
0 2 0
2 0 2
2 2 2
输出
2
样例 4
输入
2
3 2
0 1 1
0 0 2
1 1 1
输出
0
样例 5
输入
2
4 2
1 1 1
0 0 1
1 0 2
0 0 2
输出
1
数据范围与提示
对于
100
%
100\%
100% 的数据,
t
a
s
k
i
d
∈
{
1
,
2
}
,
1
≤
n
,
m
≤
500
taskid\in\{1,2\},1\leq n,m\leq500
taskid∈{1,2},1≤n,m≤500。
当
t
a
s
k
i
d
=
1
taskid=1
taskid=1 时,则
v
i
,
j
∈
{
0
,
1
,
2
}
v_{i,j}\in\{0,1,2\}
vi,j∈{0,1,2}。
当
t
a
s
k
i
d
=
2
taskid=2
taskid=2 时,则
v
i
,
j
∈
{
0
,
1
}
,
c
i
∈
[
1
,
m
]
v_{i,j}\in\{0,1\},c_i\in[1,m]
vi,j∈{0,1},ci∈[1,m]。
s
u
b
t
a
s
k
1
(
50
p
t
s
)
:
t
a
s
k
i
d
=
1
{\rm subtask~1(50~pts)}:taskid=1
subtask 1(50 pts):taskid=1。
s
u
b
t
a
s
k
2
(
50
p
t
s
)
:
t
a
s
k
i
d
=
2
{\rm subtask~2(50~pts)}:taskid=2
subtask 2(50 pts):taskid=2。
L
i
b
r
e
O
J
P
o
w
e
r
e
d
b
y
S
Y
Z
O
J
N
G
_{{\rm LibreOJ}~{\tt Powered~by}~{\rm SYZOJ~NG}}
LibreOJ Powered by SYZOJ NG
题解
用到的知识很多。
首先,我们知道一个
n
×
n
n\times n
n×n 的矩阵是满秩的,等价于它的行列式非
0
0
0 ,那么选
m
m
m 个向量,是否能成为
V
V
V 的一组基底,就取决于它们拼成的
m
×
m
m\times m
m×m 矩阵是否行列式非
0
0
0 。
对于
s
u
b
t
a
s
k
1
\rm subtask~1
subtask 1 ,我们可以把答案表示为:
∑
1
≤
i
1
<
i
2
<
.
.
.
<
i
m
≤
n
[
∣
—
v
i
1
→
—
—
v
i
2
→
—
⋮
—
v
i
m
→
—
∣
≢
0
]
m
o
d
3
\sum_{1\leq i_1<i_2<...<i_m\leq n} \left[~\left|\begin{matrix} —\overset{\rightarrow}{v_{i_1}}—\\ —\overset{\rightarrow}{v_{i_2}}—\\ \vdots\\ —\overset{\rightarrow}{v_{i_m}}—\\ \end{matrix}\right|\not\equiv0~\right]\mod 3
1≤i1<i2<...<im≤n∑⎣⎢⎢⎢⎢⎡ ∣∣∣∣∣∣∣∣∣∣—vi1→——vi2→—⋮—vim→—∣∣∣∣∣∣∣∣∣∣≡0 ⎦⎥⎥⎥⎥⎤mod3
中间那个条件符号不好处理啊!但是我们知道
1
2
,
2
2
1^2,2^2
12,22 在模
3
3
3 意义下都是等于
1
1
1 的,也就是说,把行列式平方,刚好同余于该条件表达式!那么我们就平方试试,顺便把其中一个行列式矩阵转置一下:
∑
1
≤
i
1
<
i
2
<
.
.
.
<
i
m
≤
n
∣
∣
∣
∣
∣
v
i
1
→
v
i
2
→
…
v
i
m
→
∣
∣
∣
∣
∣
⋅
∣
—
v
i
1
→
—
—
v
i
2
→
—
⋮
—
v
i
m
→
—
∣
m
o
d
3
\sum_{1\leq i_1<i_2<...<i_m\leq n} \left|\begin{matrix} |&|&|&|\\ \overset{\rightarrow}{v_{i_1}}&\overset{\rightarrow}{v_{i_2}}&\dots&\overset{\rightarrow}{v_{i_m}}\\ |&|&|&|\\ \end{matrix}\right| \cdot \left|\begin{matrix} —\overset{\rightarrow}{v_{i_1}}—\\ —\overset{\rightarrow}{v_{i_2}}—\\ \vdots\\ —\overset{\rightarrow}{v_{i_m}}—\\ \end{matrix}\right| \mod 3
1≤i1<i2<...<im≤n∑∣∣∣∣∣∣∣vi1→∣∣vi2→∣∣…∣∣vim→∣∣∣∣∣∣∣⋅∣∣∣∣∣∣∣∣∣∣—vi1→——vi2→—⋮—vim→—∣∣∣∣∣∣∣∣∣∣mod3
再运用 B
i
n
e
t
_
C
a
u
c
h
y
\tt Binet\_Cauchy
Binet_Cauchy 公式,可以知道上式就等于
det
(
(
∣
∣
∣
∣
v
1
→
v
2
→
…
v
n
→
∣
∣
∣
∣
)
⋅
(
—
v
1
→
—
—
v
2
→
—
⋮
—
v
n
→
—
)
)
\det\left(\left(\begin{matrix} |&|&|&|\\ \overset{\rightarrow}{v_{1}}&\overset{\rightarrow}{v_{2}}&\dots&\overset{\rightarrow}{v_{n}}\\ |&|&|&|\\ \end{matrix}\right) \cdot \left(\begin{matrix} —\overset{\rightarrow}{v_{1}}—\\ —\overset{\rightarrow}{v_{2}}—\\ \vdots\\ —\overset{\rightarrow}{v_{n}}—\\ \end{matrix}\right)\right)
det⎝⎜⎜⎜⎜⎛⎝⎛∣v1→∣∣v2→∣∣…∣∣vn→∣⎠⎞⋅⎝⎜⎜⎜⎜⎛—v1→——v2→—⋮—vn→—⎠⎟⎟⎟⎟⎞⎠⎟⎟⎟⎟⎞
因此求这个行列式就行了。
对于
s
u
b
t
a
s
k
2
\rm subtask~2
subtask 2 ,在模
2
2
2 意义下,并没有变得更简单,而是多加了颜色条件。我们可以这样翻译这个条件:所选的
m
m
m 个向量的颜色必须互不相同,每种颜色都要有向量。
这让我们又想到了一个关于行列式的性质:若行列式的某一行或某一列全为
0
0
0,那么行列式为
0
0
0 。
因此,我们可以用一个矩阵
A
A
A 表示颜色,
A
i
,
j
A_{i,j}
Ai,j 定义为向量
i
i
i 的颜色是(
1
1
1)否(
0
0
0)为
j
j
j 。每种颜色都要有向量,也就等价于
A
A
A 中对应的
m
×
m
m\times m
m×m 的子矩阵每行每列都有恰好一个
1
1
1 ,行列式不为
0
0
0 。
由于是取模
2
2
2 ,向量组成的行列式本身就等价于不等于
0
0
0 的条件表达式,可以不用平方。我们就把
A
A
A 的行列式乘过来表示答案:
∑
1
≤
i
1
<
i
2
<
.
.
.
<
i
m
≤
n
∣
∣
∣
∣
∣
v
i
1
→
v
i
2
→
…
v
i
m
→
∣
∣
∣
∣
∣
⋅
∣
A
i
1
,
1
A
i
1
,
2
…
A
i
1
,
m
A
i
2
,
1
A
i
2
,
2
…
A
i
2
,
m
⋮
⋮
⋱
⋮
A
i
m
,
1
A
i
m
,
2
…
A
i
m
,
m
∣
m
o
d
2
\sum_{1\leq i_1<i_2<...<i_m\leq n} \left|\begin{matrix} |&|&|&|\\ \overset{\rightarrow}{v_{i_1}}&\overset{\rightarrow}{v_{i_2}}&\dots&\overset{\rightarrow}{v_{i_m}}\\ |&|&|&|\\ \end{matrix}\right| \cdot \left|\begin{matrix} A_{i_1,1}&A_{i_1,2}&\dots&A_{i_1,m}\\ A_{i_2,1}&A_{i_2,2}&\dots&A_{i_2,m}\\ \vdots&\vdots&\ddots&\vdots\\ A_{i_m,1}&A_{i_m,2}&\dots&A_{i_m,m}\\ \end{matrix}\right| \mod 2
1≤i1<i2<...<im≤n∑∣∣∣∣∣∣∣vi1→∣∣vi2→∣∣…∣∣vim→∣∣∣∣∣∣∣⋅∣∣∣∣∣∣∣∣∣Ai1,1Ai2,1⋮Aim,1Ai1,2Ai2,2⋮Aim,2……⋱…Ai1,mAi2,m⋮Aim,m∣∣∣∣∣∣∣∣∣mod2
又可以使用
B
i
n
e
t
_
C
a
u
c
h
y
\tt Binet\_Cauchy
Binet_Cauchy 公式了,把它变为
det
(
(
∣
∣
∣
∣
v
1
→
v
2
→
…
v
n
→
∣
∣
∣
∣
)
⋅
A
)
\det\left(\left(\begin{matrix} |&|&|&|\\ \overset{\rightarrow}{v_{1}}&\overset{\rightarrow}{v_{2}}&\dots&\overset{\rightarrow}{v_{n}}\\ |&|&|&|\\ \end{matrix}\right) \cdot A\right)
det⎝⎛⎝⎛∣v1→∣∣v2→∣∣…∣∣vn→∣⎠⎞⋅A⎠⎞
直接求行列式。
复杂度都是
O
(
n
3
)
O(n^3)
O(n3) 。
CODE
代
码
并
不
一
定
是
博
客
终
结
的
地
方
^{_{代码并不一定是博客终结的地方}}
代码并不一定是博客终结的地方
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXN 505
#define ENDL putchar('\n')
#define LL long long
#define DB double
#define lowbit(x) ((-x) & (x))
LL read() {
LL f = 1,x = 0;char s = getchar();
while(s < '0' || s > '9') {if(s=='-')f = -f;s = getchar();}
while(s >= '0' && s <= '9') {x=x*10+(s-'0');s = getchar();}
return f * x;
}
int n,m,i,j,s,o,k;
int MOD = 1;
struct mat{
int n,m;
int s[500][500];
mat(){n=m=0;memset(s,0,sizeof(s));}
inline void set(int N,int M) {n=N;m=M;}
}X,A;
inline mat operator * (mat a,mat b) {
mat c;c.set(a.n,b.m);
for(int i = 0;i < a.n;i ++) {
for(int k = 0;k < a.m;k ++) {
if(a.s[i][k])
for(int j = 0;j < b.m;j ++) {
c.s[i][j] += a.s[i][k]*b.s[k][j];
}
}
}
for(int i = 0;i < c.n;i ++) {
for(int j = 0;j < c.m;j ++) c.s[i][j] %= MOD;
}return c;
}
mat T_mat(mat a) {
for(int i = 0;i < a.n;i ++) {
for(int j = i;j < a.m;j ++) {
swap(a.s[i][j],a.s[j][i]);
}
}
swap(a.n,a.m); return a;
}
int det(mat a) {
if(a.n != a.m) return 0;
int as = 1;
for(int i = 0;i < a.n;i ++) {
if(!(a.s[i][i]%MOD))
for(int j = i;j < a.n;j ++) {
if(a.s[j][i]%MOD) {swap(a.s[i],a.s[j]);as = MOD-as;break;}
}
if(!(a.s[i][i]%MOD)) return 0;
for(int j = i+1;j < a.n;j ++) {
if(a.s[j][i]%MOD) {
for(int k = a.m-1;k >= i;k --) {
(a.s[j][k] += MOD-a.s[i][k]*a.s[i][i]*a.s[j][i]%MOD) %= MOD;
}
}
}
}
for(int i = 0;i < a.n;i ++) as = as * a.s[i][i] % MOD;
return (as+MOD)%MOD;
}
int main() {
int op = read();
MOD = 4-op;
n = read(); m = read();
X.set(m,n);
A.set(n,m);
for(int i = 0;i < n;i ++) {
for(int j = 0;j < m;j ++) {
X.s[j][i] = read()%MOD;
}
if(op == 2) A.s[i][read()-1] = 1;
}
printf("%d\n",op == 1 ? det(X * T_mat(X)) : det(X * A));
return 0;
}
后记
这道题好像是行列式和
B
i
n
e
t
_
C
a
u
c
h
y
\tt Binet\_Cauchy
Binet_Cauchy 公式的板题?
不论如何,给诸队爷出这种题,
T
L
Y
\tt TLY
TLY 太阳神 也算仁慈了。
这个公式不是很常见,但是却又的确在
N
O
I
\tt NOI
NOI 大纲里。这样的知识也能掌握,祂必定是把行列式学透了的!不论学什么都深入学透,这就是我们和真正天才们的区别。
也是凡人和神的区别。
「2020-2021 集训队作业」Yet Another Linear Algebra Problem(行列式,Binet-Cauchy 公式)的更多相关文章
- LOJ 3399 -「2020-2021 集训队作业」Communication Network(推式子+组合意义+树形 DP)
题面传送门 一道推式子题. 首先列出柿子,\(ans=\sum\limits_{T_2}|T_1\cap T_2|·2^{T_1\cap T_2}\) 这个东西没法直接处理,不过注意到有一个柿子 \( ...
- IOI 2020 国家集训队作业
\(\checkmark\) 试题一 完成情况 试题二 完成情况 试题三 完成情况 cf549E cf674G arc103_f \(\checkmark\) cf594E agc034_f agc0 ...
- GitHub 公布 2021 Top 10 博文「GitHub 热点速览」
作者:HelloGitHub-小鱼干 2021 年在这周彻底同我们告别了,在本周的「News 快读」模块你可以看到过去一年 GitHub 的热门文章,其中有我们熟悉的可能让很多程序员"失业& ...
- 「THP3考前信心赛」解题报告
目录 写在前面&总结: T1 T2 T3 T4 写在前面&总结: \(LuckyBlock\) 良心出题人!暴力分给了 \(120pts\) \(T1\) 貌似是个结论题,最后知道怎么 ...
- 众安「尊享e生」果真牛的不可一世么?
近日,具有互联网基因的.亏损大户(成立三年基本没盈利,今年二季度末亏损近4亿,你能指望它多厉害?).财产险公司—众安推出“尊享e生”中高端医疗保险(财险公司经营中高端医疗真的很厉害?真的是中高端医疗险 ...
- XCActionBar 「Xcode 中的 Alfred」
下载地址:https://github.com/pdcgomes/XCActionBar 基本命令: (1)「command+shift+8」或者双击「command」键可以打开「动作输入框窗口」 ( ...
- Git 执行 「fork 出来的仓库」和「最新版本的原仓库」内容同步更新
当我们在 GitHub 上 fork 出一个仓库后,如果原仓库更新了,此时怎样才能保证我们 fork 出来的仓库和原仓库内容一致呢?我们一般关注的是仓库的 master(主干分支)的内容,通过以下步骤 ...
- 翻译「C++ Rvalue References Explained」C++右值引用详解 Part1:概述
本文系对「C++ Rvalue References Explained」 该文的翻译,原文作者:Thomas Becker. 该文较详细的解释了C++11右值引用的作用和出现的意义,也同时被Scot ...
- 苹果搜索广告后台大揭秘,最全最细致详解,手把手设置教程「后附官方视频」-b
WWDC2016 搜索广告分会视频和 PPT 发布了,ASO100 带开发者第一时间了解 Search Ads 后台设置(文末有原声视频). 首先介绍一下搜索广告的模式和竞价规则 广告模式为 CPT( ...
随机推荐
- 渗透开源工具之sqlmap安装配置环境变量教程
由于计算机安全牵涉到很多方面,建议自己在服务器上搭建自己的靶场,如何搭建靶场请订阅并查看作者上期教程,这里作者先为大家推荐一个免费开源升级靶场:https://hack.zkaq.cn/ 在封神台 ...
- bitmap技术解析:redis与roaringBitmap
bitmap的表象意义是,使用一个01标识位来表示是否的状态,可以达到节省空间和高效判定的效果.在我们的实际工作中,也有着许多的应用场景,相信了解bitmap定会给你带来一些额外的收获. 1. bit ...
- 【python基础】第10回 周总结
路径 可以简单的理解为路径就是某个事物所在的具体位置(坐标) 1.相对路径:必须有一个参考系,就是相对于自己的目标文件的位置. 2.绝对路劲:不需要有参考系,是指文件在硬盘上真正存在的路径. 计算机五 ...
- Linux 磁盘挂载和swap空间管理
挂载:把指定的设备和根下面的某个文件夹建立关联 卸载:解除两者关系的过程 挂载文件系统:mount 格式:mount device mountpoint --- mount 设备名 挂载点 mount ...
- Node.js精进(8)——错误处理
在 Node.js 中,提供了 error 模块,并且内置了标准的 JavaScript 错误,常见的有: EvalError:在调用 eval() 函数时出现问题时抛出该错误. SyntaxErro ...
- labview从入门到出家2--将“加法程序”制作成“exe应用程序”
1.上一章主要讲了如何跑我们的第一个加法程序(这里向第一个程序的鼻祖"hello world"致敬),这一章我们直接进入主题,将我们写的程序生成exe文件放桌面运行. 2.要生成e ...
- 字节输入流_InputStream类&FileInputStream类介绍和字节输入流读取字节数据
java.io.InputStream:字节输入流 此抽象类是表示字节输入流的所有类的超类 定义了所有子类共性的方法: int read()从输入流中读取数据的下一个字节 int read(byte[ ...
- 可落地的DDD(7)-战术设计上的一些误区
背景 几年前我总结过DDD战术设计的一些落地经验可落地的DDD(5)-战术设计,和一次关于聚合根的激烈讨论最近两年有些新的落地体验,回过头来发现,当初对这些概念的理解还是没有深入,这篇文章重新阐述下. ...
- jdbc 03:注册驱动的方式
jdbc连接mysql时,注册驱动的方式 package com.examples.jdbc.o3_注册驱动方式; //mysql驱动所在的包 import com.mysql.jdbc.Driver ...
- 简单易用的任务队列-beanstalkd
概述 beanstalkd 是一个简单快速的分布式工作队列系统,协议基于 ASCII 编码运行在 TCP 上.其最初设计的目的是通过后台异步执行耗时任务的方式降低高容量 Web 应用的页面延时.其具有 ...