我感到恶心

题目

题目背景
′ ′ I    f e e l    s i c k . ′ ′ ''\rm I\;feel\;sick.'' Ifeelsick.

题目描述
给一个 n × m n\times m n×m 01 01 01 矩阵,问有多少个子矩阵在模 2 2 2 意义下的秩为 k k k

数据范围与提示
n , m , k ≤ 500 n,m,k\le 500 n,m,k500,时间限制 5 s 5\rm s 5s

对 “秩” 的解释:从线性代数的角度说,它是线性无关的向量数量。从 O I OI OI 的角度说,把每一行看成一个 2 2 2 进制数,“秩” 就是其线性基的元素个数。

思路

肯定是部分枚举。考虑先枚举左边界,再从上到下枚举下边界。

我们在一维线性基问题中,常常有这样一种贪心策略:尽量使用编号大的值。不难发现,这样的结果 等价于直接从反方向插入元素。那么,由于我们已枚举了下边界,最暴力的做法就是再枚举一个上边界,然后依次加入每一行对应的二进制数。利用这一招就可以把这一步操作优化掉。

不妨以左边为高位、右边为低位。我们求一个数组 x i x_i xi 表示第 i i i 行代表的二进制数在线性基中对应的位置。即,在线性基的一顿操作下,它最终变成了一个最高位对应第 x i x_i xi 列的二进制数。由线性基的过程,可以知道,如果右边界不包含 x i x_i xi,那么这个数字就会插入失败。换句话说,能够插入成功当且仅当右边界包含 x i x_i xi

把所有第 i i i 行、第 x i x_i xi 列的点标记出来,问题转化为,矩形内必须恰好有 k k k 个点。容斥一下,转化为 ≤ k \le k k,然后 t w o    p o i n t e r s \rm two\;pointers twopointers 同时移动上边界和右边界即可。因为 x i x_i xi 的范围足够下,可以桶排(计数排序)求出右端点移动带来的点的数量改变。

计算一下复杂度。对于一个左端点,做了 n n n 行的线性基,如果用 b i t s e t \tt bitset bitset 优化,就是 O ( n 4 w ) \mathcal O({n^4\over w}) O(wn4) 的。而 t w o    p o i n t e r s \rm two\;pointers twopointers 只有 O ( n 3 ) \mathcal O(n^3) O(n3) 的复杂度。估计也蛮卡常的?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值