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". ...
随机推荐
- LeetCode 292 Nim Game 解题报告
题目要求 You are playing the following Nim Game with your friend: There is a heap of stones on the table ...
- 我的grunt学习笔记
什么是grunt? Grunt是一个JavaScript任务运行器,用于自动执行频繁任务(如压缩,编译,单元测试)的工具.它使用命令行界面来运行在文件中定义的自定义任务(这个文件称为Gruntfil ...
- 洛谷P4587 神秘数 [FJOI2016] 主席树
正解:主席树 解题报告: 先放下传送门QAQ 首先可以先思考如果只有一组询问,怎么解决 可以这么想,最开始一个数也麻油的时候能表示的最大的数是0嘛 然后先排个序,按顺序每次新加入一个数x,设加入这个数 ...
- java各版本简单对比
1995.5 Oak ——>java1.0 提出 write once run anywhere 1996.1 jdk1.0 jvm Sun Classic VM 1997.2 JDK1.1 ...
- 【雅思】【写作】【大作文】Discuss both views and give your own opinion
•Discuss both views and give your own opinion • • •Agree or disagree •Discuss both views •Report ...
- SQL SERVER 基于数据库镜像的主从同步(数据库镜像实践汇总)
SQL SERVER 基于数据库镜像的主从同步 Author:chaoqun.guo createtime:2019-03-26 目录 SQL SERVER 基于数据库镜像的主从同步... 1 ...
- OC侧滑删除
做侧滑的时候发现一个问题,当一个UITableView的cell有的有侧滑,有的没有,当用editActionsForRowAtIndexPath方法的时候发现有点问题,查看了下api,需要用到can ...
- cxPivotGrid导出数据
导出数据,需要在uses区域引用cxExportPivotGridLink 根据导出类型使用以下过程 procedure cxExportPivotGridToHTML procedure cxExp ...
- MySQL语法和用户授权
管理数据库 create database 等同于 create schema #导入数据库脚本 MariaDB [db1]> source /root/mysql/hellodb_in ...
- git diff 与 git diff --cached的不用
git diff比较的是工作目录中当前文件和暂存区域快照之间的差异, 也就是修改之后还没有暂存起来的变化内容.若要查看已暂存的将要添加到下次提交里的内容,可以用 git diff --cached 命 ...