题解[51nod1555] 布丁怪
题解[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] 布丁怪的更多相关文章
- 【51Nod1555】布丁怪
[51Nod1555]布丁怪 题面 51Nod 题目大意: 给你一个\(n\times n\)的棋盘以及\(n\)个棋子,每个棋子坐标为\((x_i,y_i)\),保证棋盘的每一行或一列都有且仅有一个 ...
- 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 ...
- ETO的公开赛T3《寻星》 题解(BY 超級·考場WA怪 )
题解 寻星 题意:给定一个有向带权图,定义从一点到另一点的某条路径长为路径上所有边权的最大值,并给定四个点编号w,t1,t2,t3. 求出一个点s,使它在到t1,t2,t3三点最短路径最大值最大或者根 ...
- 虎符ctf-MISC-奇怪的组织(看完官方题解,找到了)
一道取证题,一整场比赛,基本就死磕了这一题 写的很乱,因为当时的思维就是那么乱,完全没有注意到出题人的提示, 还没做出来,没有找到关键key 那个人的real name 文档:虎符.note链接:ht ...
- 洛谷 P3201 梦幻布丁 题解
(这篇题解可能没什么营养,主要是记录一下我用map乱搞启发式合并的神奇做法) 首先我们知道,我们肯定要用一堆集合维护每一种数当前的位置,并支持合并和数连续出现的段数两种操作 我发现这个东西并不好搞,但 ...
- noip2000提高组题解
事实再次向我证明了RP的重要性... 第一题:进制转换 是我最没有把握AC的一道题目却是我唯一一道AC的题目,真是讽刺.看完题目几乎完全没有往正常的解法(取余倒序)去想,直接写了搜索,因为数据范围在2 ...
- [HNOI2009]梦幻布丁 算法技巧之邻接链
题目描述 N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的四个布丁一共有3段颜色. 输入输出格式 输入格式: 第 ...
随机推荐
- python读取文件行数和某行内容
学习记录: python计算文件的行数和读取某一行内容的实现方法 - nkwy2012 - 博客园https://www.cnblogs.com/nkwy2012/p/6023710.html 文本文 ...
- TCP--粘包拆包,netty的解决方式
TCP基于链接的协议,并且保证有序性. 但是,每个包的长度,需要明确,否则会发生粘包现象. 以下示例为一个自定义协议的例子,其中包含了拆包的内容. 所有的类: 协议类: public class Pe ...
- OOM与StackOverFlow发生的原因及解决办法【待完成】
1,Out Of Memery 内存耗尽 1,1 产生原因 1.1.1 内存用完[堆内存] package com.cnblogs.mufasa; import org.junit.Test; imp ...
- WebUploader 上传图片回显
/* fileMaxCount 最大文件数 buttonText 按钮文本 multiple 是否多选 */ (function ($) { $.fn.extend({ uploadImg: func ...
- Java之协程(quasar)
一.前面我们简单的说了一下,Python中的协程原理.这里补充Java的协程实现过程.有需要可以查看python之协程. 二.Java协程,其实做Java这么久我也没有怎么听过Java协程的东西,但是 ...
- C++报错:error C3874
解决: 1.class 定义之后不要忘记分号 2.主函数写为int main() { }
- 《图解HTTP》摘录
# 图解HTTP 第 1 章 了解Web及网络基础 1.1使用http协议访问web 客户端:通过发送请求获取服务器资源的Web浏览器等. Web使用一种名为 HTTP(HyperText Trans ...
- iOS音频学习笔记三:音频会话管理
使用Audio Session API ,可以指定App需要的音频行为,比如,当播放音频时,使得其他应用App静音或者混和在一起,也可以指定当App的音频被中断(例如被电话)时的行为,还 ...
- [转]預防 Android Dex 64k Method Size Limit
转载自:http://ingramchen.io/blog/2014/09/prevention-of-android-dex-64k-method-size-limit.html 08 Septem ...
- SQLSEVER刚建表时主键自增
alter table 表名 drop column ID alter table 表名 add ID int identity(1,1)