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 ...
随机推荐
- C语言练手游戏-控制台输出一个会移动的坦克
把C语言的知识融合起来做一个练手的小游戏项目,将自己掌握到的数据结构.数组.函数.宏定义等知识综合利用,增加对语法的熟练程度. 操作系统: windows 10 x64 编译IDE : VS2015 ...
- 腾讯云外网IP直通后,遇到网络问题
通过内网机器,先重启网卡 service network restart cd /usr/local/etc ./modify_route.sh
- Linux系统编程【转】
转自:https://blog.csdn.net/majiakun1/article/details/8558308 一.Linux系统编程概论 1.1 系统编程基石 syscall: libc:标准 ...
- gdb revert, Go to previous line in gdb
Yes! With the new version 7.0 gdb, you can do exactly that! The command would be "reverse-step& ...
- Node 7.6默认支持Async/Await
Node.js 7.6正式默认支持async/await功能,并能够使低内存设备获得更出色的性能. Node 7.6对async/await的支持来自于将V8(Chromium JavaScript引 ...
- [转]VS2015 Git 源码管理工具简单入门
VS2015 Git 源码管理工具简单入门 1.VS Git插件 1.1 环境 VS2015+GitLab 1.2 Git操作过程图解 1.3 常见名词解释 拉取(Pull):将远程版本库合并到本 ...
- DES加密模式详解
DES加密模式详解 http://www.cnblogs.com/Lawson/archive/2012/05/20/2510781.html http://www.blogjava.net/wayn ...
- zabbix3.0.4使用shell脚本和zabbix自带模板两种方法添加对指定进程和端口的监控
zabbix3.0.4添加对进程的监控: 方法一:通过自定义命令进行监控 主要思路: 通过 ps -ef|grep sdk-push-1.0.0.jar |grep -v grep|wc -l 这个命 ...
- Expm 1_1 实现基于分治法的归并排序算法.
package org.xiu68.exp.exp1; public class Exp1_1 { public static void main(String[] args) { // TODO A ...
- Spring整合strus2简单应用总结
本身strus2没接触过,所以这块学的一知半解,正常不整合的还没学(接着学) step: 1.创建web工程 2.在/WEB-INF/lib引入jar包 asm-3.3.jarasm-commons- ...