CF627E Orchestra [矩阵计数]
\(\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 [矩阵计数]的更多相关文章
- All-one Matrices
All-one Matrices 单调栈 最大全一矩阵计数 #include<bits/stdc++.h> #define maxn 3005 using namespace std; # ...
- 斯坦福NLP课程 | 第2讲 - 词向量进阶
作者:韩信子@ShowMeAI,路遥@ShowMeAI,奇异果@ShowMeAI 教程地址:http://www.showmeai.tech/tutorials/36 本文地址:http://www. ...
- [spoj104][Highways] (生成树计数+矩阵树定理+高斯消元)
In some countries building highways takes a lot of time... Maybe that's because there are many possi ...
- [Sdoi2017]序列计数 [矩阵快速幂]
[Sdoi2017]序列计数 题意:长为\(n \le 10^9\)由不超过\(m \le 2 \cdot 10^7\)的正整数构成的和为\(t\le 100\)的倍数且至少有一个质数的序列个数 总- ...
- hdu 2865 Polya计数+(矩阵 or 找规律 求C)
Birthday Toy Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- BZOJ_4818_[Sdoi2017]序列计数_矩阵乘法
BZOJ_4818_[Sdoi2017]序列计数_矩阵乘法 Description Alice想要得到一个长度为n的序列,序列中的数都是不超过m的正整数,而且这n个数的和是p的倍数.Alice还希望 ...
- 生成树的计数 Matrix-Tree(矩阵树)定理
信息学竞赛中,有关生成树的最优化问题如最小生成树等是我们经常遇到的,而对生成树的计数及其相关问题则少有涉及.事实上,生成树的计数是十分有意义的,在许多方面都有着广泛的应用.本文从一道信息学竞赛中出现的 ...
- [SDOI2009]HH去散步 「矩阵乘法计数」
计数问题也许可以转化为矩阵乘法形式 比如若该题没有不能在一条边上重复走的条件限制,那么直接将邻接矩阵转化为矩阵乘法即可 故 矩阵乘法计数 对于计数问题,若可以将 \(n\) 个点表示成 \(n \ti ...
- 【BZOJ 4818】 4818: [Sdoi2017]序列计数 (矩阵乘法、容斥计数)
4818: [Sdoi2017]序列计数 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 560 Solved: 359 Description Al ...
随机推荐
- pycharm+gitee【代码上传下载】实战(windows详细版)
pycharm+gitee环境搭建好以后应该如何进行代码上传下载操作呢?举几个例子,此文会一直更新 环境:2019社区版pycharm+gitee+git 系统:windows系统 一.代码上传功能 ...
- windows环境搭建dubbo服务
windows环境搭建dubbo服务 1:首先需要下载dubbo的注册中心 zookeeper zookeeper注册中心下载地址链接:http://mirror.bit.edu.cn/apache/ ...
- vue中使用vue-pdf插件显示pdf
最近项目需求需要在vue中展示pdf,上网搜索了实现方法,找到vue-pdf这个插件非常好用,并且还有许多方法.属性能进行功能扩展. 一.安装 npm install --save vue-pdf 二 ...
- manjaro系统的回滚操作
作为linux系统的爱好者,自从使用linux后,就喜欢追求新的软件,连系统都换成了滚动升级的版本.manjaro基于arch linux,同时也是kde的支持系统,升级非常频繁.使用了几年,很少碰到 ...
- 随机采样方法整理与讲解(Acceptance-Rejection、MCMC、Gibbs Sampling等)
本文是对参考资料中多篇关于sampling的内容进行总结+搬运,方便以后自己翻阅.其实参考资料中的资料写的比我好,大家可以看一下!好东西多分享!PRML的第11章也是sampling,有时间后面写到P ...
- office2010安装不了提示已经安装32位的了怎么办
1.打开控制面板,查看是否有安装的程序没有拆卸,如果没有继续往下看,如果有直接拆卸掉,再进行下面的步骤. 2.首先打开注册列表.按下win+R键即可打开,输入regedit,也可以在开始菜单中搜索re ...
- session机制,浏览器禁用cookie后,怎么使用session
sessionid是存储在cookie中的,解决方案如下: Session URL重写,保证在客户端禁用或不支持COOKIE时,仍然可以使用Session session机制.session机制是一种 ...
- mysql skip-grant-tables 后要多次重启 和验证登录检查确认密码生效
mysql skip-grant-tables 后要多次重启 和验证登录检查确认密码生效
- pycharm设置代码行的长度为79字符(PEP8)
pycharm设置代码行的长度为79字符
- linux设置程序运行超时时间
在某些情况下,我们需要限制程序的运行时间(比如cronjob等),这里简单介绍下使用信号及timeout的实现方法 1. 假如有如下代码(test_timout.sh): #!/bin/bash wh ...