题解[51nod1555] 布丁怪

题面

解析

本文参考这位dalao的题解

首先有一个巧妙的转换,

开一个数组记录每个横坐标的纵坐标,

简单来说就是对于点(x,y),令a[x]=y.

于是问题就变成了求满足区间最大值与最小值的差恰好等于区间长度的区间数.

于是可以考虑分治不要问我怎么想到的

设当前区间为l,r,中点为mid.

mx[i]=i~mid的最大值(l<=mid),mid+1到i的最大值(i>mid)

mn[i]同理.

分情况讨论:

1.区间最大值和最小值都在左边.

设右端点为j,这时候j要满足mn[j+1]<mn[i]或mx[j+1]>mx[i],否则j+1也在mn~mx这个范围里面,j肯定不能是端点.

然后再看j-i是否等于mx[i]-mn[i].

2.最大值在左边,最小值在右边.

因为mx和mn都是单调的,所以拿两个指针L和R维护满足要求的右端点,

然后设右端点为j,则mx[i]-mn[j]=j-i,

即mx[i]+i=mn[j]+j,

开个桶维护一下就行了.

code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
#define fre(x) freopen(x".in","r",stdin),freopen(x".out","w",stdout)
using namespace std; inline int read(){
int sum=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
return f*sum;
} const int N=1000005;
int n,a[N];ll ans,cnt[N];
int mx[N],mn[N]; inline void work(int l,int r,int m){
mx[m]=mn[m]=a[m];
for(int i=m-1;i>=l;i--){
mx[i]=max(mx[i+1],a[i]);
mn[i]=min(mn[i+1],a[i]);
}
mx[m+1]=mn[m+1]=a[m+1];
for(int i=m+2;i<=r;i++){
mx[i]=max(mx[i-1],a[i]);
mn[i]=min(mn[i-1],a[i]);
}
int L=m+1,R=m,j=m;
for(int i=m;i>=l;i--){
while(j<r&&mx[j+1]<mx[i]&&mn[j+1]>mn[i]) j++;
if(mx[i]-mn[i]==j-i&&j>m) ans++;
while(R<r&&mx[R+1]<mx[i]) R++,cnt[R+mn[R]]++;
while(L<=r&&mn[L]>mn[i]) cnt[L+mn[L]]--,L++;
if(L<=R) ans+=cnt[i+mx[i]];
}
while(L<=r) cnt[L+mn[L]]--,L++;
while(R<r) R++,cnt[R+mn[R]]++;
} inline void solve(int l,int r){
if(l==r){ans++;return ;}
int mid=(l+r)>>1;
solve(l,mid);solve(mid+1,r);
work(l,r,mid);
reverse(a+l,a+r+1);
if((r-l+1)%2) mid--;
work(l,r,mid);
reverse(a+l,a+r+1);
} signed main(){
n=read();
for(int i=1;i<=n;i++)
{int x=read();a[x]=read();}
solve(1,n);
printf("%lld\n",ans);
return 0;
}

题解[51nod1555] 布丁怪的更多相关文章

  1. 【51Nod1555】布丁怪

    [51Nod1555]布丁怪 题面 51Nod 题目大意: 给你一个\(n\times n\)的棋盘以及\(n\)个棋子,每个棋子坐标为\((x_i,y_i)\),保证棋盘的每一行或一列都有且仅有一个 ...

  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. ETO的公开赛T3《寻星》 题解(BY 超級·考場WA怪 )

    题解 寻星 题意:给定一个有向带权图,定义从一点到另一点的某条路径长为路径上所有边权的最大值,并给定四个点编号w,t1,t2,t3. 求出一个点s,使它在到t1,t2,t3三点最短路径最大值最大或者根 ...

  6. 虎符ctf-MISC-奇怪的组织(看完官方题解,找到了)

    一道取证题,一整场比赛,基本就死磕了这一题 写的很乱,因为当时的思维就是那么乱,完全没有注意到出题人的提示, 还没做出来,没有找到关键key 那个人的real name 文档:虎符.note链接:ht ...

  7. 洛谷 P3201 梦幻布丁 题解

    (这篇题解可能没什么营养,主要是记录一下我用map乱搞启发式合并的神奇做法) 首先我们知道,我们肯定要用一堆集合维护每一种数当前的位置,并支持合并和数连续出现的段数两种操作 我发现这个东西并不好搞,但 ...

  8. noip2000提高组题解

    事实再次向我证明了RP的重要性... 第一题:进制转换 是我最没有把握AC的一道题目却是我唯一一道AC的题目,真是讽刺.看完题目几乎完全没有往正常的解法(取余倒序)去想,直接写了搜索,因为数据范围在2 ...

  9. [HNOI2009]梦幻布丁 算法技巧之邻接链

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

随机推荐

  1. Python-05-字符串格式化

    一.百分号方式 %[(name)][flags][width].[precision]typecode (name)      可选,用于选择指定的key flags          可选,可供选择 ...

  2. WUSTOJ 1344: still水题(Java)进制转换

    题目链接:1344: still水题 Description 送AC,不解释 Input 输入两个整数n和b,b表示该数的进制(包含2.8.16进制,多组数组) Output 输出该整数(10进制,每 ...

  3. Go语言学习笔记(8)——包和结构体

    包 —— 每个可执行的应用程序必须包含一个主函数,它是执行的入口点.主函数应该存在main包中. 结构体: 通过 . 操作符访问结构体的各个成员! 1. 定义结构体类型person: type per ...

  4. linux 磁盘占用的排查流程

    Linux 服务器在使用过程中可能会遇到各种问题,其中之一就是"没有可用空间". 遇到这种情况,就需要进行排查,定位到消耗了磁盘的那个文件夹. 流程如下: 1. df -h df ...

  5. javascript基本类型和对象

    JS 中分为七种内置类型,七种内置类型又分为两大类型:基本类型和对象(Object). 基本类型 null undefined boolean number string symbol 其中 JS 的 ...

  6. typescript 入门教程三

    类型别名 下面的代码将string类型赋值给一个别名,以后如果出现别名的地方,就好比出现类型string,同理其他类型也一样 type Name=string let gender:Name='男' ...

  7. 【转载】C#通过IndexOf方法判断某个字符串是否包含在另一个字符串中

    C#开发过程中针对字符串String类型的操作是常见操作,有时候需要判断某个字符串是否包含在另一个字符串,此时可以使用IndexOf方法以及Contain方法来实现此功能,Contain方法返回Tru ...

  8. 1+x证书学习日志——css 基本选择符

    ##css选择符                 1:类型选择符 直接用标签名称当作选择符                     特点:选中所有同类元素                 2:id名称 ...

  9. SMARTY的简单实例写法

    访问页面main.php(后台页面) <?php include("../init.inc.php"); //引入入口文件 include("../DBDA.php ...

  10. linux IPC简单学习

    Posix和system v区别 所谓的IPC(进程间通信)指的是消息队列,共享内存,信号量3种机制合并起来,当然,这是个狭义的概念,只包含这三种.IPC又可以分为system v进程间通信和posi ...