也许更好的阅读体验

\(\mathcal{Description}\)

题目大意 有一个\(r * c\)的矩阵上有\(n\)个点,问有多少个子矩阵里包含至少\(k\)个点

输入格式 第一行四个数\(r,c,n,k\),接下来\(n\)行,每行两个数\(x_i,y_i\),表示第\(i\)个点的坐标

输出格式 一行一个数表示合法子矩阵个数

数据范围 \(1\leq r,c,n\leq 3000 , 1\leq k\leq \min(n,10)\)

\(\mathcal{Solution}\)

这题好难

题目要求至少包含了\(k\)个点的子矩阵,\(k\)很小

朴素的想法是枚举上边界,下边界,然后在中间尺取,这样是\(O\left(n^3\right)\)的

反过来考虑,从下往上枚举每一行

先算出以这一行的每个顶点为左上角,最下面一行为第\(c\)的所有合法矩阵个数

计算方法考虑尺取即可

再考虑最下面一行逐渐往上走的合法矩阵个数

这个过程中,点是在不断变少的

考虑算出将最下面一行变为其上面那一行时合法矩阵的减少量,再用原来的合法矩阵量减去,得到最下面一行往上移一行后的合法矩阵数量

如何计算合法矩阵的减少量

枚举这一行中的每个点,计算出包含这个点且点数刚好为\(k\)的矩阵个数,然后删去这个点

计算方法也是尺取,另外,尺取时用一个链表表示该行中下一个点和上一个点的位置,这样尺取复杂度就是该行点数,而不是\(m\)

这样就能算出删去这一行中所有点后不合法的矩阵个数

那么往上移一行合法矩阵就会减去这些矩阵

如此计算,总复杂度为

\(O\left(n^2k+npk\right)\)

如有不懂之处,请参考代码

如仍有不懂之处可在评论提出,博主看到会给予回复

\(\mathcal{Code}\)

/*******************************
Author:Morning_Glory
LANG:C++
Created Time:2019年10月15日 星期二 15时37分21秒
*******************************/
#include <cstdio>
#include <fstream>
#include <vector>
#define ll long long
using namespace std;
const int maxn = 3005;
int n,m,p,k;
int s[maxn],t[maxn],last[maxn],nxt[maxn];
ll ans;
vector <int> dot[maxn];
int main()
{
scanf("%d%d%d%d",&n,&m,&p,&k);//求n行m列p个点至少包含k个点的矩阵个数
for (int i=1;i<=p;++i){
int x,y;
scanf("%d%d",&x,&y);
dot[x].push_back(y);//每行的点
} for (int u=n;u>=1;--u){
for (int i=0;i<dot[u].size();++i) ++s[dot[u][i]];//s[i] -> 第n行到第u行上第i列的点数
int l=1,r=0,num=0;
ll inc=0;
while (true){
while (r+1<=m&&num<k) num+=s[++r];
if (num<k) break;
while (l<=r&&num>=k) num-=s[l++],inc+=m-r+1;//inc 合法矩阵个数
} for (int i=1;i<=m;++i) t[i]=s[i];
for (int i=0;i<=m+1;++i) last[i]=i-1,nxt[i]=i+1;
for (int i=1;i<=m;++i)
if (!s[i]) last[nxt[i]]=last[i],nxt[last[i]]=nxt[i]; for (int d=n;d>=u;--d){
ans+=inc; for (int i=0;i<dot[d].size();++i){ int cur=dot[d][i],sl=t[cur],sr=0;
l=r=cur;
while (nxt[r]<=m&&sl+sr+t[nxt[r]]<=k) sr+=t[r=nxt[r]]; while (true){
if (sl+sr==k) inc-=(l-last[l])*(nxt[r]-r);
sl+=t[l=last[l]];
if (!l||sl>k) break;
while (sl+sr>k) sr-=t[r],r=last[r];
} --t[cur];
if (!t[cur]) last[nxt[cur]]=last[cur],nxt[last[cur]]=nxt[cur];
}
}
} printf("%lld\n",ans);
return 0;
}

如有哪里讲得不是很明白或是有错误,欢迎指正

如您喜欢的话不妨点个赞收藏一下吧

CF627E Orchestra [矩阵计数]的更多相关文章

  1. All-one Matrices

    All-one Matrices 单调栈 最大全一矩阵计数 #include<bits/stdc++.h> #define maxn 3005 using namespace std; # ...

  2. 斯坦福NLP课程 | 第2讲 - 词向量进阶

    作者:韩信子@ShowMeAI,路遥@ShowMeAI,奇异果@ShowMeAI 教程地址:http://www.showmeai.tech/tutorials/36 本文地址:http://www. ...

  3. [spoj104][Highways] (生成树计数+矩阵树定理+高斯消元)

    In some countries building highways takes a lot of time... Maybe that's because there are many possi ...

  4. [Sdoi2017]序列计数 [矩阵快速幂]

    [Sdoi2017]序列计数 题意:长为\(n \le 10^9\)由不超过\(m \le 2 \cdot 10^7\)的正整数构成的和为\(t\le 100\)的倍数且至少有一个质数的序列个数 总- ...

  5. hdu 2865 Polya计数+(矩阵 or 找规律 求C)

    Birthday Toy Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  6. BZOJ_4818_[Sdoi2017]序列计数_矩阵乘法

    BZOJ_4818_[Sdoi2017]序列计数_矩阵乘法 Description Alice想要得到一个长度为n的序列,序列中的数都是不超过m的正整数,而且这n个数的和是p的倍数.Alice还希望 ...

  7. 生成树的计数 Matrix-Tree(矩阵树)定理

    信息学竞赛中,有关生成树的最优化问题如最小生成树等是我们经常遇到的,而对生成树的计数及其相关问题则少有涉及.事实上,生成树的计数是十分有意义的,在许多方面都有着广泛的应用.本文从一道信息学竞赛中出现的 ...

  8. [SDOI2009]HH去散步 「矩阵乘法计数」

    计数问题也许可以转化为矩阵乘法形式 比如若该题没有不能在一条边上重复走的条件限制,那么直接将邻接矩阵转化为矩阵乘法即可 故 矩阵乘法计数 对于计数问题,若可以将 \(n\) 个点表示成 \(n \ti ...

  9. 【BZOJ 4818】 4818: [Sdoi2017]序列计数 (矩阵乘法、容斥计数)

    4818: [Sdoi2017]序列计数 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 560  Solved: 359 Description Al ...

随机推荐

  1. 微信小程序七夕节礼物

    VSCode Node.js HbuilderX 安装前端开发环境 [外链图片转存失败(img-aXUJRfXc-1565136341881)(https://upload-images.jiansh ...

  2. Python3菜鸟教程笔记

    多行语句 同一行显示多条语句 Print 输出

  3. HTML盒子模型冷知识!!!

    一.边框    1.边框颜色     border-color 边框颜色(可以设置上边框,如:border-top-color,也可以整体设置,但是要注意顺序)     2.边框粗细     bord ...

  4. SDN阅读作业(二)

    前言碎碎念 当我看到这个全英论文以后,身体和心理都出现了戒断反应,让人无比难受,毕竟自己很久没做过英语阅读理解了.总之,在舍友大佬的帮助下以及各款翻译软件的鼎力支持之下(通篇读完后还是找了中文文献来对 ...

  5. es6学习2:变量的解构赋值

    一:数组的解构赋值 ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构 let [foo, [[bar], baz]] = [1, [[2], 3]]; foo bar ba ...

  6. Jmeter(十七)_jmeter与java_selenium自动化

    Jmeter可以通过WebDriver来完成UI自动化测试,也可以测试浏览器端对系统的压力,需要以下jiar包 基本配置 1:下载JMeterPlugins-WebDriver-1.3.1.zip,解 ...

  7. 使用CAS实现单点登录功能

    目录 单点登录 简介 CAS服务器部署 上传tomcat服务器压缩到文件夹/usr/local/cas目录下,解压,修改tomcat文件夹名为tomcat 修改tomcat配置文件的端口号 关闭tom ...

  8. MariaDB主从复制虚拟机实战

    MariaDB简介: MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可 MariaDB的目的是完全兼容MySQL,包括API和命令行,使之能轻松成为MySQ ...

  9. 分类的性能评估:准确率、精确率、Recall召回率、F1、F2

    import numpy as np import pandas as pd from sklearn.feature_extraction.text import TfidfVectorizer f ...

  10. 机动车驾驶(1)--- 禁令标志汇总 by John

    以下是普通标志牌(新车安全)