【51Nod1555】布丁怪

题面

51Nod

题目大意:

给你一个\(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】布丁怪的更多相关文章

  1. 题解[51nod1555] 布丁怪

    题解[51nod1555] 布丁怪 题面 解析 本文参考这位dalao的题解 首先有一个巧妙的转换, 开一个数组记录每个横坐标的纵坐标, 简单来说就是对于点(x,y),令a[x]=y. 于是问题就变成 ...

  2. 51Nod 1555 布丁怪

    题目描述: 布丁怪这一款游戏是在一个n×n 的矩形网格中进行的,里面有n个网格有布丁怪,其它的一些格子有一些其它的游戏对象.游戏的过程中是要在网格中移动这些怪物.如果两个怪物碰到了一起,那么他们就会变 ...

  3. Codeforces 436D Pudding Monsters

    题意简述 开始有无限长的一段格子,有n个格子种有布丁怪兽,一开始连续的布丁怪兽算一个布丁怪兽. 每回合你可以将一个布丁怪兽向左或右移动,他会在碰到第一个布丁怪兽时停下,并与其合并. 有m个特殊格子,询 ...

  4. [CF436D]Pudding Monsters

    题目大意:有一个长度为$2\times 10^5$的板,有$n(n\leqslant 10^5)$个格子$a_1,\dots,a_n$有布丁怪兽,一开始连续的怪兽算一个怪兽,有$m(m\leqslan ...

  5. 第一个独立开发的游戏 怪斯特:零 已经上线APP STORE!

    今天是个值得纪念的日子,而且是双喜临门 2年多来的摸爬滚打,终于有了回报 第一喜:自己独立开发的游戏 怪斯特:零 已经通过审核并上架APP STORE! 第二喜:迈入了自己期待2年之久的游戏行业,年后 ...

  6. 1483:[HNOI]2009 梦幻布丁 - BZOJ

    Description N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的四个布丁一共有3段颜色. Input 第 ...

  7. bzoj 1483 [HNOI2009]梦幻布丁(链表+启发式合并)

    1483: [HNOI2009]梦幻布丁 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1818  Solved: 761[Submit][Status ...

  8. 数据结构(启发式合并):HNOI 2009 梦幻布丁

    Description N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的四个布丁一共有3段颜色. Input 第 ...

  9. 【BZOJ1483】【链表启发式合并】梦幻布丁

    Description N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的四个布丁一共有3段颜色. Input 第 ...

随机推荐

  1. Unreal Engine 4 系列教程 Part 8:粒子系统教程

    .katex { display: block; text-align: center; white-space: nowrap; } .katex-display > .katex > ...

  2. LeetCode 142:环形链表 II Linked List Cycle II

    给定一个链表,返回链表开始入环的第一个节点. 如果链表无环,则返回 null. 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始). 如果 pos 是 - ...

  3. 运维相关指标数据采集并ES入仓 - 运维笔记

    为了进行数字化IT治理,需要对一些应用进程相关指标进行采集并入库.收集到的应用指标数据最好要进行ES入仓,入到Kafka里面,并通过Kibana可视化展示. 需要进行采集的应用进程相关指标如下: ES ...

  4. NXP官方的i.mx6ul板级uboot源码适配

    1.前言 CoM-P6UL是盈鹏飞科技有限公司基于NXP原厂I.MX6UL芯片生产研发的核心板,本文将对CoM-P6UL适配NXP的基于Linux4.1.15版本的uboot板级源码. 2.开发环境 ...

  5. 【MySQL】MMM和MHA高可用架构

    用途 对MySQL主从复制集群的Master的健康监控. 当Master宕机后把写VIP迁移到新Master. 重新配置集群中的其他Slave从新Master同步 MMM架构 主服务器发生故障时, 1 ...

  6. Java Scanner 类——获取用户的输入

    创建Scanner对象语法 Scanner scan = new Scanner(System.in); 使用next()获取输入的字符串 import java.util.Scanner; publ ...

  7. Binding ,抄自 http://www.cnblogs.com/cnblogsfans/archive/2011/02/19/1958586.html

    1. 绑定到其它元素 <Grid> <StackPanel > <TextBox x:Name="textBox1" Height="150 ...

  8. 2、Ext.NET 1.7 官方示例笔记-按钮

    这一节应该比较简单,因为按钮相对其他控件还是比较简单的,但按钮是最常用的控件,先从简单的开始,才能循序渐进的学下去不是吗? 从上面的图片可以看出,可分基本&按钮组,先看下基本的Overview ...

  9. 第三方web ide开发环境下vuejs开发HMR环境搭建-码农这样开发是快乐的!

    vuejs是一个非常优秀的前端框架,利用该框架可以快速开发出任何web app,之所以vuejs开发非常高效快捷,其中最重要的一点就是利用webpakc提供的HMR(热模块替换)特性,可以边写vue组 ...

  10. phpmyadmin 在服务起上检测到错误,请查看窗口底部

    使用phpmyadmin一直提示这个警告,看着难受: 解决: 修改文件:/etc/phpmyadmin/config.inc.php 在最后添加这一句, $cfg['SendErrorReports' ...