『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 图标设计示例,希望能带给你设计灵 ...
随机推荐
- 进阶Java编程(11)ClassLoader类加载器【待完成】
1,ClassLoader类加载器简介 在Java里面提供一个系统的环境变量:ClassPath,这个属性的作用主要是在JVM进程启动的时候进行类加载路径的定义,在JVM里面可以根据类加载器而后进行指 ...
- C# 使用Emit实现动态AOP框架 进阶篇之异常处理
目 录 C# 使用Emit实现动态AOP框架 (一) C# 使用Emit实现动态AOP框架 (二) C# 使用Emit实现动态AOP框架 (三) C# 使用Emit实现动态AOP框架 进阶篇之异常处 ...
- JS基础_相等运算符
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- O050、Create Volume 操作 (Part I)
参考https://www.cnblogs.com/CloudMan6/p/5603312.html 前面已经学习了Cinder的架构和相关组件,从本节开始详细分析 Cinder 的各种操作,首先 ...
- [leetcode] 题解记录 11-20
博客园markdown太烂, 题解详情https://github.com/TangliziGit/leetcode/blob/master/solution/11-20.md Leetcode So ...
- form表单中的enctype 属性以及post请求里Content-Type方式
对于form表单中的enctype 属性之前理解的一般,就知道是类似于一种编码形式.后来公司做一个form表单提交数据的时候,重点是这个form表单里有文件上传,而我又要用vue来模拟form表单提交 ...
- 修改this的指向
call var a={ name:'xuux', fn:function(a,b){ console.log(a+b); console.log(this);//{name: "xuux& ...
- C# 移除数组中重复项
方法一: static void Main(string[] args) { //看到数组的第一反应应该是排序 ,,,,,,,}; //去掉数组中重复的项 //先排序 arrayAsc(array); ...
- mysql一些语句
<!-- 报警量排行按创建时间每月来排行 --> <select id="alarmDaySort" resultType="alarm"&g ...
- Golang Gateway API 搭建教程
原文链接 随着微服务的兴起,行业里出现了非常多优秀的微服务网关框架,今天教大家搭建一套国人,用Golang写的微服务网关框架. 这里啰嗦一句,可能到今天还有人不理解什么是微服务,为什么要用微服务.目前 ...