4558: [JLoi2016]方
4558: [JLoi2016]方
https://lydsy.com/JudgeOnline/problem.php?id=4558
分析:
容斥原理+各种神奇的计数。
如果没有被删除了的点的话,直接计算就好了。
统计出所有的竖直放置的正方形,然后每个正方形里包含其边长个数正方形。

设外边的正方形边长为a,公式就是$(n - a + 1) \times (m - a + 1) * a$,所以可以O(n)求出。
考虑减不合法的正方形。那么分为包含一个“坏点”,2个,3个,4个。
234的时候都可以直接枚举两个点,然后就可以确定出其他的两个点了,(这里可以确定两个点后,把所有枚举到的都加上,最后除以计算了多少次。三个的可以分别枚举三条边的时候都算上,所以除以3;4个点枚举边和对角线都算上了,所以除以6)。1个的最难算。
我们把一个点面向的四个方向分开计算,因为这是一个一样的过程。
可以知道,如果确定了一个点,和一个正方形(这个点在正方形的边上),那么就会确定唯一的一个以这个点为顶点的正方形

那么我们只需要计算有多少个正方形的边上有这个点就行了,

如果没有左边和右边的限制的话:

如上图,左边和右边长度都为4,先不管是否超出边界,那么就是2,3,4...8,9,分别表示长度为1,2,3...7,8的正方形。就是$\frac{n \times (n+3)}{2}$。
加上边界h的限制,正方形的边长最大为h。加上左右边界的限制,正方形的最大边长为$min(l+r,h)$,设为$z$。
这样算出来,可能是有不合法的,左边界超出了,或者右边界超出了。

于是根据等差序列求和公式,可以直接算了。
还有一点,计算这些正方形的时候,超四个方向的和加起来,会重复计算一部分。

最后根据容斥原理,算出来就行了。
代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<cctype>
#include<set>
#include<queue>
#include<vector>
#include<map>
using namespace std;
typedef long long LL; inline int read() {
int x=,f=;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for(;isdigit(ch);ch=getchar())x=x*+ch-'';return x*f;
} const int N = ;
const int mod = 1e8 + ; struct Point{
int x, y;
Point() {}
Point(int _x,int _y) { x = _x, y = _y; }
}A[N];
int n, m;
LL ans, t1, t2, t3, t4;
set<LL> s; LL Count1(int l,int r,int h) {
int z = min(l + r, h);
if (z == ) return ;
LL ans = 1ll * z * (z + ) / ;
if (z > l) ans -= 1ll * (z - l) * (z - l + ) / ;
if (z > r) ans -= 1ll * (z - r) * (z - r + ) / ;
return (ans + mod) % mod;
}
LL Calc1(int x,int y) { // 统计一个点可以作为多少个正方形的顶点。
int u = x, d = n - x, l = y, r = m - y;
LL ans = Count1(l, r, u) + Count1(l, r, d) + Count1(u, d, l) + Count1(u, d, r); ans %= mod;
ans = ans - min(u, l) - min(u, r) - min(d, l) - min(d, r);
return (ans + mod) % mod;
}
bool inmap(Point P) {
return (P.x >= && P.x <= n && P.y >= && P.y <= m);
}
void Calc234(Point P,Point Q) {
if (!inmap(P) || !inmap(Q)) return ;
int t = s.count(1ll * P.x * (m + ) + P.y) + s.count(1ll * Q.x * (m + ) + Q.y);
++ t2;
if (t >= ) t3 ++;
if (t >= ) t3 ++, t4 ++;
}
int main() {
n = read(), m = read();int k = read();
for (int i = ; i <= k; ++i) {
A[i].x = read(), A[i].y = read();
s.insert(1ll * A[i].x * (m + ) + A[i].y); // 因为列是从0开始编号的,所以需要乘以(m+1),或者直接乘以2000000
}
for (int i = , lim = min(n, m); i <= lim; ++i) {
ans += (1ll * (n - i + ) * (m - i + ) % mod * i % mod);
if (ans >= mod) ans -= mod;
}
for (int i = ; i <= k; ++i) {
t1 += Calc1(A[i].x, A[i].y);
if (t1 >= mod ) t1 -= mod;
}
for (int i = ; i <= k; ++i) {
Point P = A[i];
for (int j = i + ; j <= k; ++j) {
Point Q = A[j];
int dx = A[i].x - A[j].x, dy = A[i].y - A[j].y;
Calc234(Point(P.x + dy, P.y - dx), Point(Q.x + dy, Q.y - dx)); // 作为边的情况
Calc234(Point(P.x - dy, P.y + dx), Point(Q.x - dy, Q.y + dx));
if ((abs(dx) + abs(dy)) & ) continue;
int dx2 = (dx - dy) / , dy2 = (dx + dy) / ;
Calc234(Point(P.x - dx2, P.y - dy2), Point(Q.x + dx2, Q.y + dy2)); // 作为对角线的情况
}
}
ans = ans - t1 + t2 - t3 / + t4 / ;
ans = (ans + mod) % mod;
cout << ans;
return ;
}
4558: [JLoi2016]方的更多相关文章
- 【BZOJ 4558】 4558: [JLoi2016]方 (计数、容斥原理)
未经博主同意不能转载 4558: [JLoi2016]方 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 362 Solved: 162 Descri ...
- BZOJ.4558.[JLOI2016]方(计数 容斥)
BZOJ 洛谷 图基本来自这儿. 看到这种计数问题考虑容斥.\(Ans=\) 没有限制的正方形个数 - 以\(i\)为顶点的正方形个数 + 以\(i,j\)为顶点的正方形个数 - 以\(i,j,k\) ...
- 【BZOJ】4558: [JLoi2016]方
[题意]给定有(n+1)*(m+1)个点的网格图,其中指定k个点不合法,求合法的正方形个数(四顶点合法). [算法]计数 [题解]斜着的正方形很麻烦,所以考虑每个斜正方形其外一定有正的外接正方形. 也 ...
- bzoj4558[JLoi2016]方 容斥+count
4558: [JLoi2016]方 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 452 Solved: 205[Submit][Status][D ...
- bzoj千题计划281:bzoj4558: [JLoi2016]方
http://www.lydsy.com/JudgeOnline/problem.php?id=4558 容斥原理 全部的正方形-至少有一个点被删掉的+至少有两个点被删掉的-至少有3个点被删掉的+至少 ...
- bzoj4558: [JLoi2016]方
Description 上帝说,不要圆,要方,于是便有了这道题.由于我们应该方,而且最好能够尽量方,所以上帝派我们来找正方形 上帝把我们派到了一个有N行M列的方格图上,图上一共有(N+1)×(M+1) ...
- [BZOJ4558]:[JLoi2016]方(容斥+模拟)
题目传送门 题目描述 上帝说,不要圆,要方,于是便有了这道题.由于我们应该方,而且最好能够尽量方,所以上帝派我们来找正方形上帝把我们派到了一个有N行M列的方格图上,图上一共有$(N+1)\times ...
- JLOI2016 方
bzoj4558 真是一道非常excited的题目啊-JLOI有毒 题目大意:给一个(N+1)*(M+1)的网格图,格点坐标为(0~N,0~M),现在挖去了K个点,求剩下多少个正方形(需要注意的是正方 ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
随机推荐
- .NET中制做对象的副本(二)继承对象之间的数据拷贝
定义学生 /// <summary> /// 学生信息 /// </summary> public class Student { /// <summary> // ...
- 为cobbler自动化安装系统工具添加epel源
关于cobbler的安装及部署,参考:CentOS 6.5自动化运维之基于cobbler服务的自动化安装操作系统详解http://blog.csdn.net/reblue520/article/det ...
- DOS命令大全(转)
dos命令大全 CMD是command的缩写,是windows环境下的虚拟DOS窗口,提供有DOS命令,功能强大,如果你以前学习过DOS操作,那就小儿科了.是基于Windows的命令行窗口,在开始-- ...
- SpringMVC(2):Spring MVC入门
原文出处: 张开涛 2.1.Spring Web MVC是什么 spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思 ...
- java 对象锁学习
机制 锁机制是用来解决多线程共享资源时产生的冲突问题的.java 为每一个对象关联一个对象锁,通常把锁分为对象锁和类锁,他们的本质都是对象锁,只不过对象锁关联的是类的 Object 对象 (java. ...
- ThinkPHP中如何获取指定日期后工作日的具体日期
思路: 1.获取到查询年份内所有工作日数据数组2.获取到查询开始日期在工作日的索引3.计算需查询日期索引4.获得查询日期 /*创建日期类型记录表格*/ CREATE TABLE `tb_workday ...
- HDU 5988 Coding Contest(费用流+浮点数)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5988 题目大意: 给定n个点,m条有向边,每个点是一个吃饭的地方,每个人一盒饭.每个点有S个人,有B盒 ...
- python接口自动化测试五:乱码、警告、错误处理
乱码: 以content字节流输出,解码成utf-8: print(r.encoding) # 查看返回的编码格式: 去掉Warning警告: import urllib3 urllib3.dis ...
- MonologFX最简demo,javafx外用dialog示例
参考blog:https://blogs.oracle.com/javajungle/entry/monologfx_floss_javafx_dialogs_for /* * To change t ...
- PR2017添加字幕文本或文字水印
1.新建一个文本图层(先点击下右下方区域,避免新建图层是灰色不可用) 2.可以看到已经新建了一个文本图层,然后可以在效果控件修改属性,可以用文字工具在文字的地方进行修改文本.(注意点击T图标才能编辑文 ...