『HGOI 20190917』Lefkaritika 题解 (DP)
题目概述
一个$n \times m$的整点集。其中$q$个点被m被设置为不能访问。
问这个点集中含有多少个不同的正方形,满足不包含任何一个不能访问的点。
对于$50\%$的数据满足$1 \leq n,m \leq 10^4, 1 \leq q \leq 10^3$
对于另外$50\%$的数据满足$1 \leq n,m \leq 2\times 10^5, 1 \leq q \leq 200$
Solution
我们规定行递增的方向为$x$的正方向,列递增的方向为$y$的正方向。
设$f[i][j]$表示以$(i,j)$为左上角的正方形最大边长。
则$\sum\limits_{i=1}^{n} \sum\limits_{j=1}^{m} f[i][j]$就是所求。
我们可以枚举对角线,然后再枚举每个标记点,分别计算各个标记点对这条对角线的影响。
不妨设当前直线是$y = x + b$。
- 若点$(i,j)$在直线下方(即顺时针方向),其会限制到点$(j-b,j)$左上方的所有点。
- 若点$(i,j)$在直线上,其会限制到这个点左上方的所有点。
- 若点$(i,j)$在直线上方(即逆时针方向),其会限制到点$(i,i+b)$左上方的所有点
注意到,对于每一条对角线,由于标记点个数是$q$个,那么限制的记录点最多也是$q$个。
两个记录点间的转移可以使用一些数学计算来加速做到$O(1)$,但是需要注意非常多的细节。
人傻常数大,后面用一个set,复杂度到了$O(nq \ log_2 \ q)$
# pragma GCC optimize()
# include<bits/stdc++.h>
# define int long long
using namespace std;
const int N=2e5+;
int n,m,q;
namespace fast_IO{
const int IN_LEN = , OUT_LEN = ;
char ibuf[IN_LEN], obuf[OUT_LEN], *ih = ibuf + IN_LEN, *oh = obuf, *lastin = ibuf + IN_LEN, *lastout = obuf + OUT_LEN - ;
inline char getchar_(){return (ih == lastin) && (lastin = (ih = ibuf) + fread(ibuf, , IN_LEN, stdin), ih == lastin) ? EOF : *ih++;}
inline void putchar_(const char x){if(oh == lastout) fwrite(obuf, , oh - obuf, stdout), oh = obuf; *oh ++= x;}
inline void flush(){fwrite(obuf, , oh - obuf, stdout);}
int read(){
int x = ; int zf = ; char ch = ' ';
while (ch != '-' && (ch < '' || ch > '')) ch = getchar_();
if (ch == '-') zf = -, ch = getchar_();
while (ch >= '' && ch <= '') x = x * + ch - '', ch = getchar_(); return x * zf;
}
void write(int x){
if (x < ) putchar_('-'), x = -x;
if (x > ) write(x / );
putchar_(x % + '');
}
}
set< pair<int,int> >st;
struct point { int x,y;}r[N];
int cross(point a,point b) {
return a.x*b.y-a.y*b.x;
}
int direct (point a,point b,point c) {
point ba={a.x-b.x,a.y-b.y};
point bc={c.x-b.x,c.y-b.y};
int ret=cross(bc,ba);
if (ret==) return ;
else if (ret<) return -;
else if (ret>) return ;
}
pair<int,int>bag[N],p[N];
int work(int b) {
int cnt=;
int Lx=max(-b,0ll),Rx=min(n,m-b);
int Ly=Lx+b,Ry=Rx+b;
for (int i=;i<=q;i++) {
int rec=direct(r[i],(point){-b,},(point){,b}); if (b<) rec=-rec;
if (b==) rec=direct(r[i],(point){-,-},(point){,});
if (rec==-) {
if (r[i].y-b>=Lx&&r[i].y-b<=Rx&&r[i].y>=Ly&&r[i].y<=Ry) bag[++cnt]=make_pair(r[i].y-b,r[i].x-r[i].y+b-);
} else if (rec==) {
if (r[i].x>=Lx&&r[i].x<=Rx&&r[i].y>=Ly&&r[i].y<=Ry) bag[++cnt]=make_pair(r[i].x,);
} else if (rec==) {
if (r[i].x>=Lx&&r[i].x<=Rx&&r[i].x+b>=Ly&&r[i].x+b<=Ry) bag[++cnt]=make_pair(r[i].x,r[i].y-r[i].x-b-);
}
}
sort(bag+,bag++cnt);
int tot=;
for (int i=,j;i<=cnt;i=j) {
j=i; int ret=bag[i].second;
while (bag[j].first==bag[i].first&&j<=cnt) j++;
p[++tot]=make_pair(bag[i].first,ret);
}
if (tot==) {
int tmp=min(n-Lx,m-Ly);
return (tmp+)*(tmp)/;
}
int ans=(min(n-(p[tot].first+),m-(p[tot].first++b)))*(min(n-(p[tot].first+),m-(p[tot].first++b))+)/;
p[tot].second=min(p[tot].second,min(n-p[tot].first,m-p[tot].first-b));
int last=-;
for (int i=tot;i>=;i--) {
if (last==-) { ans+=p[i].second; last=i; continue;}
int num=p[last].first-p[i].first-;
int val=p[last].second+;
if (st.find(make_pair(p[last].first,p[last].first+b))!=st.end()) val--;
ans+=num*(val+val+num-)/;
if (st.find(make_pair(p[last].first,p[last].first+b))!=st.end()) p[i].second=min(p[i].second,p[last].second+num);
else p[i].second=min(p[i].second,p[last].second+num+);
ans+=p[i].second;
last=i;
}
int num=p[].first-Lx;
int val=p[].second+;
if (st.find(make_pair(p[].first,p[].first+b))!=st.end()) val--;
ans+=num*(val+val+num-)/;
return ans;
}
using namespace fast_IO;
signed main() {
n=read(),m=read(),q=read(); n--; m--;
for (int i=;i<=q;i++) {
r[i].x=read();r[i].y=read();
r[i].x--; r[i].y--;
st.insert(make_pair(r[i].x,r[i].y));
}
int ans=;
for (int i=-n;i<=m;i++) ans+=work(i);
write(ans); flush();
return ;
}
Lefkaritika.cpp
『HGOI 20190917』Lefkaritika 题解 (DP)的更多相关文章
- 『HGOI 20190917』Cruise 题解 (计算几何+DP)
题目概述 在平面直角坐标系的第$1$象限和第$4$象限有$n$个点,其中第$i$个点的坐标为$(x_i,y_i)$,有一个权值$p_i$ 从原点$O(0,0)$出发,不重复的经过一些点,最终走到原点, ...
- 洛谷 P6383 -『MdOI R2』Resurrection(DP)
洛谷题面传送门 高速公路上正是补 blog 的时候,难道不是吗/doge,难不成逆在高速公路上写题/jy 首先形成的图显然是连通图并且有 \(n-1\) 条边.故形成的图是一棵树. 我们考虑什么样的树 ...
- LuoguP7337 『MdOI R4』Fun 题解
Content 有 \(n\) 个人去打比赛.给出第 \(i\) 个人的交通方式 \(t_i\) 和颓废值 \(q_i\)(均以 \(0/1\) 表示).如果 \(t_i=1,q_i=1\) 的人数 ...
- 『土地征用 Land Acquisition 斜率优化DP』
斜率优化DP的综合运用,对斜率优化的新理解. 详细介绍见『玩具装箱TOY 斜率优化DP』 土地征用 Land Acquisition(USACO08MAR) Description Farmer Jo ...
- 关于『进击的Markdown』:第二弹
关于『进击的Markdown』:第二弹 建议缩放90%食用 众里寻他千百度,蓦然回首,Markdown却在灯火灿烂处 MarkdownYYDS! 各位早上好! 我果然鸽稿了 Markdown 语法 ...
- 似魔鬼的 『 document.write 』
在平时的工作中,楼主很少用 document.write 方法,一直觉得 document.write 是个危险的方法.楼主不用,并不代表别人不用,最近给维护的项目添了一点代码,更加深了我对 &quo ...
- 拾遗:『Linux Capability』
『Linux Capability』 For the purpose of performing permission checks, traditional UNIX implementations ...
- 『创意欣赏』20款精致的 iOS7 APP 图标设计
这篇文章给大家分享20款精致的 iOS7 移动应用程序图标,遵循图形设计的现代潮流,所有图标都非常了不起,给人惊喜.通过学习这些移动应用程序图标,设计人员可以提高他们的创作,使移动用户界面看起来更有趣 ...
- 『设计前沿』14款精致的国外 iOS7 图标设计示例
每天都有大量的应用程序发布到 iOS App Store 上,在数量巨大的应用中想要引起用户的主要,首要的就是独特的图标设计.这篇文章收集了14款精致的国外 iOS7 图标设计示例,希望能带给你设计灵 ...
随机推荐
- Elastic Search中Document的CRUD操作
一. 新增Document在索引中增加文档.在index中增加document.ES有自动识别机制.如果增加的document对应的index不存在.自动创建,如果index存在,type不存在自动创 ...
- 进阶Java编程(8)反射应用案例
1,反射实例化对象 经过一系列分析之后可以发现虽然获得了Class类的实例化对象但是依然觉得这个对象获取的意义不是很大,所以为了进一步的帮助大家理解反射的核心意义所在,下面将通过几个案例进行说明(都是 ...
- js弹窗返回值详解(window.open方式)
今天在改公司一个老系统时,碰到了window.open()的这个语法.虽然这个方法有点老,不太用了.所以有点不清楚父级弹框如何获取子级页面返回的值.为了解决这个问题,上网搜了一下.原作者参考网址:ht ...
- Tomcat项目自动部署脚本
一般情况下使用的Linux环境都是加固的,root路径只有超级管理员权限才能进入.我们新建一个自己的用户,在/home下会有一个用户目录,传输war包都放在这个目录下,此时不动webapps文件下的内 ...
- Java学习笔记【八、数据结构】
参考资料: http://www.cnblogs.com/janneystory/p/5758958.html array arraylist list linklist的区别 http://www. ...
- 微服务之Nacos配置中心源码解析(二)
Nacos配置中心源码解析 源码入口 ConfigFactory.createConfigService ConfigService configService = NacosFactory.crea ...
- Linux :ssh sftp scp
SSH 概述 1 SSH协议,Secure Shell ,为客户提供安全的shel环境,默认端口22 OpenSSH服务 服务名称:sshd 主程序:/usr/bin/sshd /usr/bin ...
- QTP(2)
注意: 在使用QTP录制代码时,能使用鼠标点击的就不要使用键盘操作,能单击的操作就不要使用双击 一.QTP的工作流程 1.录制测试脚本前的准备: a.分析被测系统是否可以实现自动化测试 b.分析被测系 ...
- PAT乙级1011
题目链接 https://pintia.cn/problem-sets/994805260223102976/problems/994805312417021952 题解 很明显这题是考数值范围的,i ...
- netty-4.客户端与服务端心跳
(原) 第四篇,客户端与服务端心跳 心跳事件有三种,读空闲,写空闲,读写空闲,定义在了IdleState枚举类中,分别为READER_IDLE,WRITER_IDLE,ALL_IDLE 服务端: ma ...