枚举指的是枚举矩阵的上下界,然后根据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 (二维前缀和 + 枚举剪枝)的更多相关文章

  1. [CSP-S模拟测试]:physics(二维前缀和+二分+剪枝)

    题目传送门(内部题26) 输入格式 第一行有$3$个整数$n,m,q$.然后有$n$行,每行有一个长度为$m$的字符串,$+$表示正电粒子,$-$表示负电粒子.然后有$q$行,每行$2$个整数$x,y ...

  2. openjudge1768 最大子矩阵[二维前缀和or递推|DP]

    总时间限制:  1000ms 内存限制:  65536kB 描述 已知矩阵的大小定义为矩阵中所有元素的和.给定一个矩阵,你的任务是找到最大的非空(大小至少是1 * 1)子矩阵. 比如,如下4 * 4的 ...

  3. poj-3739. Special Squares(二维前缀和)

    题目链接: I. Special Squares There are some points and lines parellel to x-axis or y-axis on the plane. ...

  4. 计蒜客模拟赛D1T1 蒜头君打地鼠:矩阵旋转+二维前缀和

    题目链接:https://nanti.jisuanke.com/t/16445 题意: 给你一个n*n大小的01矩阵,和一个k*k大小的锤子,锤子只能斜着砸,问只砸一次最多能砸到多少个1. 题解: 将 ...

  5. Gym 102091L Largest Allowed Area 【二分+二维前缀和】

    <题目链接> 题目大意:给你一个由01组成的矩形,现在问你,该矩形中,最多只含一个1的正方形的边长最长是多少. 解题分析: 用二维前缀和维护一下矩形的01值,便于后面直接$O(1)$查询任 ...

  6. 无线网络发射选址 2014年NOIP全国联赛提高组(二维前缀和)

    P2038 无线网络发射器选址 题目描述 随着智能手机的日益普及,人们对无线网的需求日益增大.某城市决定对城市内的公共场所覆盖无线网. 假设该城市的布局为由严格平行的129 条东西向街道和129 条南 ...

  7. 【AcWing 99】激光炸弹——二维前缀和

    (题面来自AcWing) 一种新型的激光炸弹,可以摧毁一个边长为 R 的正方形内的所有的目标. 现在地图上有 N 个目标,用整数Xi,Yi表示目标在地图上的位置,每个目标都有一个价值Wi. 激光炸弹的 ...

  8. COGS1752 [BOI2007]摩基亚Mokia(CDQ分治 + 二维前缀和 + 线段树)

    题目这么说的: 摩尔瓦多的移动电话公司摩基亚(Mokia)设计出了一种新的用户定位系统.和其他的定位系统一样,它能够迅速回答任何形如“用户C的位置在哪?”的问题,精确到毫米.但其真正高科技之处在于,它 ...

  9. Good Bye 2015 C. New Year and Domino 二维前缀

    C. New Year and Domino   They say "years are like dominoes, tumbling one after the other". ...

随机推荐

  1. 洛谷P3724 大佬 [AH2017/HNOI2017] dp+bfs

    正解:dp+bfs 解题报告: 传送门! 这题看起来很复杂的样子其实真的很复杂 但是仔细看一下题目,会发现其实操作只有两个目的嘛,一个是保证自己不死,一个是让对手减血 而且保证自己不死只有一种操作 而 ...

  2. tortoisegit 常见错误disconnected no supported authentication methods available(server sent: publickey)

    按如图操作 如果不能应用,Enable Proxy Server选中,再点击下面的应用及确定. 操作完上一部,用tortoisegit 下拉一次(git pull),即可解决

  3. c语言常见编程

    //输入一个整数,然后按照原顺序输出相应字符 # import <stdio.h> void main() { void convert (int n); int a; printf (& ...

  4. mv 命令

    [root@localhost soft]# .txt [root@localhost soft]# [root@localhost soft]# ls .txt [root@localhost so ...

  5. HBase单机模式安装

    第一部分 安装前准备 1.安装hadoop 今天刚刚学了hbase的一点基础,准备安装Hbase实际操练一下.因为安装hbase的前提条件是已经成功安装了hadoop,而且hadoop的版本要和hba ...

  6. redis实现消息队列(七)

    1. 介绍 redis有一个数据类型叫list(列表),它的每个子元素都是 string 类型的双向链表.我们可以通过 push,pop 操作从链表的头部或者尾部添加删除元素.这使得 list 既可以 ...

  7. 小睿开始呼叫用户,然后FS怎么跟用户交互的整个流程原理

    学习从小睿开始呼叫用户,然后FS怎么跟用户交互的整个流程原理;     1.小睿向欣方新发起呼叫请求;     2.欣方新可以通过线路发起SIP协议请求,来呼叫用户;     3.当用户接通后,将建立 ...

  8. [sh]rm -rf*的防护和普通用户执行命令

    尽量用普通用户执行,因为普通用户无法删除root的文件,避免误删除 rm -rf 不可取, 尽量find+rm -rf 尽量cd && rm -rf * 加上逻辑 cd /tmp/re ...

  9. PHP Fatal error: Uncaught ErrorException: preg_match_all (): JIT compilation failed: no more memory in phar

    PHP 升级到 7.3 后,出现 BUG: 解决办法:修改php.ini文件,;pcre.jit=1 =>  pcre.jit=0

  10. 一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——实现篇:(八)RTP音视频传输解析层之MPA传输格式

    一.MPEG RTP音频传输 相较H264的RTP传输格式,MPEGE音频传输格式则简单许多. 每一包MPEG音频RTP包都前缀一个4字节的Header,如下图(RFC2550) “MBZ”必须为0( ...