『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 图标设计示例,希望能带给你设计灵 ...
随机推荐
- linux命令 ip
- Ruby Rails学习中:添加安全密码
接上篇 一. 添加安全密码 我们已经为 name 和 email 字段添加了验证规则, 现在要加入用户所需的最后一个常规属性: 安全密码.每个用户都要设置一个密码(还要二次确认), 数据库中则存储经过 ...
- echart4数据管理组件dataset学习
背景 如果后台数据固定,如何动态定制其前端数据展示方式呢?也就是说同一种数据,如何被多个前端Echarts图表复用呢?最近在研究一种数据展示可配置化的功能,然后发现了echart4.0的dataset ...
- OpenCV-图像处理
直方图比较方法-概述 对输入的两张图像计算得到直方图H1与H2,归一化到相同的尺度空间 然后可以通过计算H1与H2的之间的距离得到两个直方图的相似程度进 而比较图像本身的相似程度.Opencv提供的比 ...
- DVWA reCAPTCHA key: Missing
修改dvwa文件夹下文件config.inc.php change: $_DVWA[ 'recaptcha_public_key' ] = ' '; $_DVWA[ 'recaptcha_privat ...
- QT 安卓 悬浮窗权限动态申请
一:申请方式: String ACTION_MANAGE_OVERLAY_PERMISSION = "android.settings.action.MANAGE_OVERLAY_PERMI ...
- JS基础_if注意问题
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...
- Oracle连接字符串总结(转)
Oracle XE 标准连接 Oracle XE(或者"Oracle Database 10g Express Edition")是一个简单免费发布的版本. 以下是语法格式: Dr ...
- 1 sql server 中cursor的简介
1.游标的分类 游标共有3类:API服务器游标.Transaction-SQL游标和API客户端游标. 2 API服务器cursor共有如下几种 静态游标的完整结果集将打开游标时建立的结果集存储在临时 ...
- asp.net Core 2.0 MVC为Controller或Action添加定制特性实现登录验证
前言:最近在倒腾 微软的新平台 asp.net Core 2.0,在这个过程中有些东西还是存在差异.下面是我在学习过程的一点笔记.有不妥之处,望各位大虾指正! 一.先创建一个控制器继承于Control ...