【51Nod1555】布丁怪
【51Nod1555】布丁怪
题面
题目大意:
给你一个\(n\times n\)的棋盘以及\(n\)个棋子,每个棋子坐标为\((x_i,y_i)\),保证棋盘的每一行或一列都有且仅有一个棋子,问你有多少个正方形框住的棋子数数值上等于正方形的边长。
其中\(1\leq n\leq 3\times 10^5,1\leq x_i,y_i\leq n\)。
题解
首先转化一下题面,题面变为:
给你一个长度为\(n\)的数组\(a\),问你有多少个区间\([l,r]\)满足\(\max_{i=l}^ra_i-\min_{i=l}^ra_i+1=r-l+1\)。
对于这样子的一个东西,我们考虑分治。
那么我们就是要合并\([l,mid],[mid+1,r]\)这两个区间。
因为和最大/小值有关,我们对于\([l,mid]\)维护后缀\(\min/\max\),\([mid+1,r]\)维护前缀\(\min/\max\),然后按照最大/小值出现位置分类讨论一下。
- \(min,max\)在同一边,那么对于每个位置\(i\)可以确定出一个唯一与之确定的左/右端点,只需对左/右区间分别扫一遍即可。
- \(min,max\)不在同一边,那么我们假定左边取到\(\min\),右边取到\(\max\),那么一个满足条件的区间需要满足\(\max-\min=r-l\),
也就是说\(\min-l=\max-r\),可以对于每个\(\min-l,\max-r\)放进桶里维护。左\(\max\)右\(\min\)的情况同理。
代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
inline int gi() {
register int data = 0, w = 1;
register char ch = 0;
while (!isdigit(ch) && ch != '-') ch = getchar();
if (ch == '-') w = -1, ch = getchar();
while (isdigit(ch)) data = 10 * data + ch - '0', ch = getchar();
return w * data;
}
const int MAX_N = 3e5 + 5, T = 3e5;
int N, a[MAX_N], mn[MAX_N], mx[MAX_N];
int bln[MAX_N << 2];
long long ans = 0;
void Div(int l, int r) {
if (l == r) return (void)(++ans);
int mid = (l + r) >> 1;
Div(l, mid), Div(mid + 1, r);
mn[mid] = mx[mid] = a[mid];
for (int i = mid - 1; i >= l; i--) {
mn[i] = min(mn[i + 1], a[i]);
mx[i] = max(mx[i + 1], a[i]);
}
mn[mid + 1] = mx[mid + 1] = a[mid + 1];
for (int i = mid + 2; i <= r; i++) {
mn[i] = min(mn[i - 1], a[i]);
mx[i] = max(mx[i - 1], a[i]);
}
for (int i = mid; i >= l; i--) {
int len = mx[i] - mn[i] + 1;
int pos = mid + (len - (mid - i + 1));
if (pos <= mid || pos > r) continue;
if (mx[pos] >= mn[i] && mx[pos] <= mx[i] &&
mn[pos] >= mn[i] && mn[pos] <= mx[i]) ++ans;
}
for (int i = mid + 1; i <= r; i++) {
int len = mx[i] - mn[i] + 1;
int pos = mid - (len - (i - mid + 1));
if (pos > mid || pos < l) continue;
if (mx[pos] >= mn[i] && mx[pos] <= mx[i] &&
mn[pos] >= mn[i] && mn[pos] <= mx[i]) ++ans;
}
int pl = mid + 1, pr = mid + 1;
for (int i = mid; i >= l; i--) {
while (pr <= r && mn[i] < mn[pr]) bln[mx[pr] - pr + T]++, ++pr;
while (pl < pr && mx[i] > mx[pl]) bln[mx[pl] - pl + T]--, ++pl;
ans += bln[mn[i] - i + T];
}
for (int i = pl; i < pr; i++) bln[mx[i] - i + T]--;
pl = pr = mid;
for (int i = mid + 1; i <= r; i++) {
while (pr >= l && mn[i] < mn[pr]) bln[mx[pr] + pr]++, --pr;
while (pl > pr && mx[i] > mx[pl]) bln[mx[pl] + pl]--, --pl;
ans += bln[mn[i] + i];
}
for (int i = pl; i > pr; i--) bln[mx[i] + i]--;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("cpp.in", "r", stdin);
#endif
N = gi(); for (int i = 1; i <= N; i++) a[gi()] = gi();
Div(1, N);
printf("%lld\n", ans);
return 0;
}
【51Nod1555】布丁怪的更多相关文章
- 题解[51nod1555] 布丁怪
题解[51nod1555] 布丁怪 题面 解析 本文参考这位dalao的题解 首先有一个巧妙的转换, 开一个数组记录每个横坐标的纵坐标, 简单来说就是对于点(x,y),令a[x]=y. 于是问题就变成 ...
- 51Nod 1555 布丁怪
题目描述: 布丁怪这一款游戏是在一个n×n 的矩形网格中进行的,里面有n个网格有布丁怪,其它的一些格子有一些其它的游戏对象.游戏的过程中是要在网格中移动这些怪物.如果两个怪物碰到了一起,那么他们就会变 ...
- Codeforces 436D Pudding Monsters
题意简述 开始有无限长的一段格子,有n个格子种有布丁怪兽,一开始连续的布丁怪兽算一个布丁怪兽. 每回合你可以将一个布丁怪兽向左或右移动,他会在碰到第一个布丁怪兽时停下,并与其合并. 有m个特殊格子,询 ...
- [CF436D]Pudding Monsters
题目大意:有一个长度为$2\times 10^5$的板,有$n(n\leqslant 10^5)$个格子$a_1,\dots,a_n$有布丁怪兽,一开始连续的怪兽算一个怪兽,有$m(m\leqslan ...
- 第一个独立开发的游戏 怪斯特:零 已经上线APP STORE!
今天是个值得纪念的日子,而且是双喜临门 2年多来的摸爬滚打,终于有了回报 第一喜:自己独立开发的游戏 怪斯特:零 已经通过审核并上架APP STORE! 第二喜:迈入了自己期待2年之久的游戏行业,年后 ...
- 1483:[HNOI]2009 梦幻布丁 - BZOJ
Description N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的四个布丁一共有3段颜色. Input 第 ...
- bzoj 1483 [HNOI2009]梦幻布丁(链表+启发式合并)
1483: [HNOI2009]梦幻布丁 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1818 Solved: 761[Submit][Status ...
- 数据结构(启发式合并):HNOI 2009 梦幻布丁
Description N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的四个布丁一共有3段颜色. Input 第 ...
- 【BZOJ1483】【链表启发式合并】梦幻布丁
Description N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的四个布丁一共有3段颜色. Input 第 ...
随机推荐
- Unreal Engine 4 系列教程 Part 9:AI教程
.katex { display: block; text-align: center; white-space: nowrap; } .katex-display > .katex > ...
- HTML连载31-制作一个百度首页
一. 我们制作一个百度首页作为练习,可直接复制该代码保存后缀名为.html来查看 <!DOCTYPE html> <html lang="en"> < ...
- 图片服务器FastDFS的安装及使用
FastDFS介绍 FastDFS是用c语言编写的一款开源的分布式文件系统.FastDFS为互联网量身定制,充分考虑了冗余备份.负载均衡.线性扩容等机制,并注重高可用.高性能等指标,使用FastDFS ...
- elasticSearch查询(一)
**整理成sql格式来看懂elastic** 1.多个字段多个and查询 sql格式:select * from product where title = 'xxxx' and pid = 12 l ...
- 探究java对象头
探究java对象头 研究java对象头,我这里先截取Hotspot中关于对象头的描述,本文研究基于64-bit HotSpot VM 文件路径 openjdk-jdk8u-jdk8u\hotspot\ ...
- PHP 数组函数大全
PHP数组函数是核心的一部分.无需安装即可使用这些函数 函数名称 描述 array_change_key_case 将数组中的所有键名修改为全大写或小写 array_chunk 将一个数组分割成多个 ...
- 团队展示&选题 (白衣天使队)
作业详见此地址: https://www.cnblogs.com/bbplus/p/11735449.html
- 一次http请求的过程
http协议(超文本传输协议)是属于应用层的协议,网络分层:应用层(http协议,FTP),传输层(tcp,udp),网络层(ip/ARP),链路层 我们以浏览器向百度发送请求为例: http的发送: ...
- Linux命令——ethtool
转自:https://www.cnblogs.com/kelamoyujuzhen/p/10116423.html 参考:9 Linux ethtool Examples to Manipulate ...
- Microsoft Surface 2019新品发布会汇总
Microsoft Surface 2019 新品发布会汇总 10月2日晚,微软举行了Microsoft Surface 2019秋季新品发布会,本次发布会涉及如下设备内容等: SurfaceLapt ...