【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 第 ...
随机推荐
- 海边拾贝-E-第三方专栏文章
收录一些优秀的专栏文章,或者解决某类知识点的文章: Linux高性能服务器编程:https://blog.csdn.net/gatieme/column/info/high-per-server ht ...
- 在 Javascript 中,为什么给 form 添加了 onsubmit 事件,为什么 IE7/8 还是会提交表单?
参考地址:http://stackoverflow.com/questions/4078245/onsubmit-return-false-has-no-effect-on-internet-expl ...
- Kafka 2.3 Producer (0.9以后版本适用)
kafka0.9版本以后用java重新编写了producer,废除了原来scala编写的版本. 这里直接使用最新2.3版本,0.9以后的版本都适用. 注意引用的包为:org.apache.kafka. ...
- [CrackMe]160个CrackMe之002
吾爱破解专题汇总:[反汇编练习]160个CrackME索引目录1~160建议收藏备用 一.逆向分析之暴力破解 暴力破解,对于这种具有提示框的,很好定位. 定位好之后,爆破其跳转语句,就能达到破解目的. ...
- PIE属性表多字段的文本绘制
最近研究了PIE SDK文本元素的绘制相关内容,因为在我们的开发中,希望可以做到在打开一个Shp文件后,读取到属性表的所有字段,然后可以选择一些需要的字段,将这些字段的所有要素值的文本,绘制到shp图 ...
- 宣布Visual Studio Code Installer for Java
自从第一个Java语言服务器在微软苏黎世办公室的一个小型会议室的黑客马拉松中开发已经差不多3年了,该会议室的人员来自Red Hat,IBM,Codenvy和Microsoft,后来成为Visual S ...
- Python - 条件控制、循环语句 - 第十二天
Python 条件控制.循环语句 end 关键字 关键字end可以用于将结果输出到同一行,或者在输出的末尾添加不同的字符,实例如下: Python 条件语句是通过一条或多条语句的执行结果(True 或 ...
- gsoap生成webservice调用客户端接口
1.下载gsoap2.8 2.运行 wsdl2h.exe -o XXX.h XXX.wsdl wsdl文件可以是本地文件,也可以是服务器的wsdl,比如http://192.168.0.122:333 ...
- Mac OSX(Mac OS10.11) 安装 pwntools 失败的最新解决方案
pwntools是一个 CTF 框架和漏洞利用开发库,用 Python 开发,由 rapid 设计,旨在让使用者简单快速的编写 exploit. 网上针对 Mac OS 的安装教程大多都是基于 pip ...
- du查看某个文件或目录占用磁盘空间的大小
一.du的功能:`du` reports the amount of disk space used by the specified files and for each subdirectory ...