Memento Mori (二维前缀和 + 枚举剪枝)
枚举指的是枚举矩阵的上下界,然后根据p0, p1, p2的关系去找出另外的中间2个点。然后需要记忆化一些地方防止重复减少时间复杂度。这应该是最关键的一步优化时间,指的就是代码中to数组。然后就是子矩阵的一个计算了,需要用二维前缀和预处理数据,然后判断的时候直接O(1)查询就好了。
#include<bits/stdc++.h>
using namespace std; const int inf = 0x3f3f3f3f;
const int maxn = 2e3 + ;
struct node{
int x, y;
node(){}
node(int x, int y) : x(x), y(y){}
}a[maxn], b[maxn], c[maxn], X[];
int p[], matdp[maxn][maxn], to[maxn][]; bool cmp1(const node &a, const node &b){
return a.x < b.x;
}
bool cmp2(const node &a, const node &b){
return a.y > b.y;
}
bool cmp3(const node &a, const node &b){
return a.y < b.y;
} int howmany(int x1, int y1, int x2, int y2){
return matdp[x2][y2] + matdp[x1 - ][y1 - ] - matdp[x1 - ][y2] - matdp[x2][y1 - ];
}
bool isOK(){
int x1 = inf, y1 = inf, x2 = , y2 = ;
for(int i = ; i < ; i ++){
x1 = min(x1, X[i].x); x2 = max(x2, X[i].x);
y1 = min(y1, X[i].y); y2 = max(y2, X[i].y);
for(int j = i + ; j < ; j ++)
if((p[j] - p[i]) * (X[j].y - X[i].y) <= ) return false;
}
return howmany(x1, y1, x2, y2) == ;
} int main(){
int T, n, m, k, x, y;scanf("%d",&T);
while(T --){
scanf("%d%d%d", &n, &m, &k);
scanf("%d%d%d%d", &p[], &p[], &p[], &p[]);
int big = , small = , ans = ;
(p[] > p[]) ? small ++ : big ++;
(p[] > p[]) ? small ++ : big ++;
memset(matdp, , sizeof(matdp));
for(int i = ; i <= k; i ++){
scanf("%d%d", &x, &y);matdp[x][y] = ;
a[i] = b[i] = c[i] = node(x, y);
}
for(int i = ; i <= n; i ++){
for(int j = ; j <= m; j ++)
matdp[i][j] += matdp[i][j - ];
for(int j = ; j <= m; j ++)
matdp[i][j] += matdp[i - ][j];
}
sort(a + , a + k + , cmp1);
sort(b + , b + k + , cmp2);
sort(c + , c + k + , cmp3);
for(int i = ; i <= k; i ++){
X[] = a[i];
for(int j = ; j <= k; j ++)
to[j][] = to[j][] = j == k ? : j + ;
for(int j = k; j > i; j --){
if(a[i].x == a[j].x) break;
if((p[] - p[]) * (a[j].y - a[i].y) <= ) continue;
X[] = a[j]; X[] = X[] = node(-, -);
int u = , v, bi = big, sm = small, t = ;
while(sm --){
for(v = u, u = to[u][]; u; to[v][] = to[u][], v = u, u = to[u][])
if(a[i].x < b[u].x && b[u].x < a[j].x && b[u].y < a[i].y){
X[t ++] = b[u];break;
}
}
u = ;
while(bi --){
for(v = u, u = to[u][]; u; to[v][] = to[u][], v = u, u = to[u][])
if(a[i].x < c[u].x && c[u].x < a[j].x && c[u].y > a[i].y){
X[t ++] = c[u];break;
}
}
if(t < || X[].x == X[].x) continue;
if(X[].x > X[].x) swap(X[], X[]);
if(isOK()) ans ++;
}
}
printf("%d\n",ans);
}
return ;
}
Memento Mori (二维前缀和 + 枚举剪枝)的更多相关文章
- [CSP-S模拟测试]:physics(二维前缀和+二分+剪枝)
题目传送门(内部题26) 输入格式 第一行有$3$个整数$n,m,q$.然后有$n$行,每行有一个长度为$m$的字符串,$+$表示正电粒子,$-$表示负电粒子.然后有$q$行,每行$2$个整数$x,y ...
- openjudge1768 最大子矩阵[二维前缀和or递推|DP]
总时间限制: 1000ms 内存限制: 65536kB 描述 已知矩阵的大小定义为矩阵中所有元素的和.给定一个矩阵,你的任务是找到最大的非空(大小至少是1 * 1)子矩阵. 比如,如下4 * 4的 ...
- poj-3739. Special Squares(二维前缀和)
题目链接: I. Special Squares There are some points and lines parellel to x-axis or y-axis on the plane. ...
- 计蒜客模拟赛D1T1 蒜头君打地鼠:矩阵旋转+二维前缀和
题目链接:https://nanti.jisuanke.com/t/16445 题意: 给你一个n*n大小的01矩阵,和一个k*k大小的锤子,锤子只能斜着砸,问只砸一次最多能砸到多少个1. 题解: 将 ...
- Gym 102091L Largest Allowed Area 【二分+二维前缀和】
<题目链接> 题目大意:给你一个由01组成的矩形,现在问你,该矩形中,最多只含一个1的正方形的边长最长是多少. 解题分析: 用二维前缀和维护一下矩形的01值,便于后面直接$O(1)$查询任 ...
- 无线网络发射选址 2014年NOIP全国联赛提高组(二维前缀和)
P2038 无线网络发射器选址 题目描述 随着智能手机的日益普及,人们对无线网的需求日益增大.某城市决定对城市内的公共场所覆盖无线网. 假设该城市的布局为由严格平行的129 条东西向街道和129 条南 ...
- 【AcWing 99】激光炸弹——二维前缀和
(题面来自AcWing) 一种新型的激光炸弹,可以摧毁一个边长为 R 的正方形内的所有的目标. 现在地图上有 N 个目标,用整数Xi,Yi表示目标在地图上的位置,每个目标都有一个价值Wi. 激光炸弹的 ...
- COGS1752 [BOI2007]摩基亚Mokia(CDQ分治 + 二维前缀和 + 线段树)
题目这么说的: 摩尔瓦多的移动电话公司摩基亚(Mokia)设计出了一种新的用户定位系统.和其他的定位系统一样,它能够迅速回答任何形如“用户C的位置在哪?”的问题,精确到毫米.但其真正高科技之处在于,它 ...
- Good Bye 2015 C. New Year and Domino 二维前缀
C. New Year and Domino They say "years are like dominoes, tumbling one after the other". ...
随机推荐
- php面向对象的封装性
面向对象编程 1:封装性 访问修饰符,作用为封装,防止外部访问. public 公有的 private 私有的 protected 受保护的 一开始具体也没搞明白是怎么回事,搞个小的Demo就出来了 ...
- Orchard Core 模块化
在上一篇文章谈到如何搭好一个基础的Orchard Core项目. 今天要尝试Orchard Core的模块化. 我自己的理解:一个系统可以分成一个个模块,这一个个模块是由一个个类库去实现的. 首先,在 ...
- opencv 替换图像中的一部分
首先选取图像中的Roi区域,然后对Roi区域进行赋值,那么原图像相应的区域也跟着变化了: dst = src.clone(); cv::Mat Roi(dst, cv::Rect(x, y, cut_ ...
- linux中按照指定内容查找文件
grep -rnRi 指定的内容 * | awk -F":" '{print $1}' 解释: grep 查找文件内容 -r 表示递归查找 -n 表示显示行号 -R 表示查找所有文 ...
- 【接口】【面试题】http协议相关面试题
浏览器输入 url 按回车背后经历了哪些? 1.在 PC 浏览器的地址栏输入一串 URL,然后按 Enter 键这个页面渲染出来,这个过程中都发生了什么事? 1.首先,在浏览器地址栏中输入 url,先 ...
- SQL专家云监控
SQL专家云监控:http://www.zhuancloud.com/Index.html
- mysql 数据操作 目录
mysql 记录的增删改查 mysql 数据操作 单表查询 mysql 数据操作 多表查询
- WordPress如何屏蔽恶意关键词搜索
我们在用WordPress建站比较方便,但如果网站有一定的权重后,一些不怀好意的人就会过来制作恶意内容,比如故意搜索邪恶的关键词.垃圾评论等,那我们如何屏蔽恶意搜索关键词呢?不会很难,会写点代码的朋友 ...
- docker+Nexus Repository Manager 搭建私有docker仓库
使用容器安装Nexus3 1.下载nexus3的镜像: docker pull sonatype/nexus3 2.使用镜像启动一个容器: docker run -d -p 8081:8081 -p ...
- Day2 Python基础学习——字符串、列表、元组、字典、集合
Python中文学习大本营:http://www.pythondoc.com/ 一.字符串操作 一.用途:名字,性格,地址 name = 'wzs' #name = str('wzs')print(i ...