F. Pudding Monsters
time limit per test

2 seconds

memory limit per test

256 megabytes

In this problem you will meet the simplified model of game Pudding Monsters.

An important process in developing any game is creating levels. A game field in Pudding Monsters is an n × n rectangular grid, n of its cells contain monsters and some other cells contain game objects. The gameplay is about moving the monsters around the field. When two monsters are touching each other, they glue together into a single big one (as they are from pudding, remember?).

Statistics showed that the most interesting maps appear if initially each row and each column contains exactly one monster and the rest of map specifics is set up by the correct positioning of the other game objects.

A technique that's widely used to make the development process more efficient is reusing the available resources. For example, if there is a large n × n map, you can choose in it a smaller k × k square part, containing exactly k monsters and suggest it as a simplified version of the original map.

You wonder how many ways there are to choose in the initial map a k × k (1 ≤ k ≤ n) square fragment, containing exactly k pudding monsters. Calculate this number.

Input

The first line contains a single integer n (1 ≤ n ≤ 3 × 105) — the size of the initial field.

Next n lines contain the coordinates of the cells initially containing monsters. The i-th of the next lines contains two numbers ri, ci(1 ≤ ri, ci ≤ n) — the row number and the column number of the cell that initially contains the i-th monster.

It is guaranteed that all ri are distinct numbers and all ci are distinct numbers.

Output

Print the number of distinct square fragments of the original field that can form a new map.

Examples
input
5
1 1
4 3
3 2
2 4
5
output
10

题解:

考试的时候这道题真是吓到我了。。一开始以为是一道单纯的数数题,后来发现并不简单。。。

我们把这个棋盘模型抽象一下,这个棋盘由于

Statistics showed that the most interesting maps appear if initially each row and each column contains exactly one monster and the rest of map specifics is set up by the correct positioning of the other game objects.

也就是说,一行一列只有1个怪物,所以我们可以把它抽象为(化简为)一个1~n的排列

如果定义max(l,r)为区间[l,r]的最大值,min(l,r)为区间[l,r]的最小值,

我们需要的目标正方形,就对应这个排列中的某一个区间[l,r],并且满足max(l,r)-min(l,r)==r-l

接下来是关键的一步:我们考虑分治统计这些合法区间(似乎有一些类似cdq?)。

也就是说,如果设f(l,r)为区间[l,r]的合法区间数量,mi=(l+r)>>1

那么f(l,r)=f(l,mi)+f(mi+1,r)+『跨中点的合法解数量』

接下来我们考虑如何统计跨中点的合法解数量。

对于跨中点的合法解,其可能情况有4种:

1°max(l,r),min(l,r)均在左侧

2°max(l,r),min(l,r)均在右侧

3°max(l,r)在左侧,min(l,r)在右侧

4°max(l,r)在右侧,min(l,r)在左侧

简单来说,就是极值“在同侧”和“在异侧”两种情况

如果极值在同侧,我们可以枚举一个端点,并且计算出区间长度,从而得到另外一个端点,

最后判断是否合法,也即判断另外一侧是否有更大/小的极值

如果极值在异侧,我们依旧枚举其中一个端点,

(我们这里仅讨论最小值在左侧的情况,最小值在右侧的情况是与此对称的)

然后我们考虑上面的式子max(mi+1,r)-min(l,mi)==r-l

移项可得max(mi+1,r)-r==min(l,mi)-l

这样我们就可以枚举左端点,再用桶维护每个min(l,mi)-l对应的合法解个数(通过扫描右区间可得)

但要注意,min(l,mi)-l可能是负值,因此我们要给他加上一个较大值(比如N)

最后统计答案即可。代码见下:

 #include <cstdio>
#include <cstring>
using namespace std;
typedef long long LL;
const int N=;
int n,A[N],cnt[N*+],maxl[N],minl[N],maxr[N],minr[N];
inline int max(int a,int b){return a>b?a:b;}
inline int min(int a,int b){return a<b?a:b;}
LL divide(int l,int r)
{
if(l==r)return ;
register int mi=(l+r)>>,i,j,k;
LL ret=divide(l,mi)+divide(mi+,r);
maxl[mi]=minl[mi]=A[mi],maxr[mi+]=minr[mi+]=A[mi+];
for(i=mi-;i>=l;--i)maxl[i]=max(maxl[i+],A[i]),minl[i]=min(minl[i+],A[i]);
for(i=mi+;i<=r;++i)maxr[i]=max(maxr[i-],A[i]),minr[i]=min(minr[i-],A[i]);
for(i=l;i<=mi;++i)
{
j=i+maxl[i]-minl[i];
if(j<=r&&j>mi&&maxr[j]<maxl[i]&&minr[j]>minl[i])ret++;
}
for(i=r;i>mi;--i)
{
j=i-(maxr[i]-minr[i]);
if(j>=l&&j<=mi&&maxl[j]<maxr[i]&&minl[j]>minr[i])ret++;
}
for(i=mi,j=mi+,k=mi;i>=l;--i)
{
while(j<=r&&maxr[j]<maxl[i])--cnt[maxr[j]-j+N],++j;
while(k<r&&minr[k+]>minl[i])++k,++cnt[maxr[k]-k+N];
ret+=max(cnt[minl[i]-i+N],);
}
for(i=mi+;i<=r;++i)cnt[maxr[i]-i+N]=;
for(i=mi,j=mi+,k=mi;i>=l;--i)
{
while(j<=r&&minr[j]>minl[i])--cnt[minr[j]+j],++j;
while(k<r&&maxr[k+]<maxl[i])++k,++cnt[minr[k]+k];
ret+=max(cnt[maxl[i]+i],);
}
for(i=mi+;i<=r;++i)cnt[minr[i]+i]=;
return ret;
}
int main()
{
scanf("%d",&n);int a,b;register int i,j;
for(i=;i<=n;++i)scanf("%d%d",&a,&b),A[a]=b;
printf("%I64d\n",divide(,n));
}

这道题的代码实现不是很难,但是这种模型的转换,以及分治的想法是很excellent的,真是长见识了。

我不经常用分治的方法解题……以后刷题的时候要多想想这方面的解法了。

[Codeforces526F]Pudding Monsters 分治的更多相关文章

  1. CodeForces526F:Pudding Monsters (分治)

    In this problem you will meet the simplified model of game Pudding Monsters. An important process in ...

  2. 【CF526F】Pudding Monsters cdq分治

    [CF526F]Pudding Monsters 题意:给你一个排列$p_i$,问你有对少个区间的值域段是连续的. $n\le 3\times 10^5$ 题解:bzoj3745 Norma 的弱化版 ...

  3. Codeforces 526F Pudding Monsters - CDQ分治 - 桶排序

    In this problem you will meet the simplified model of game Pudding Monsters. An important process in ...

  4. CF526F Pudding Monsters

    CF526F Pudding Monsters 题目大意:给出一个\(n* n\)的棋盘,其中有\(n\)个格子包含棋子. 每行每列恰有一个棋子. 求\(k*k\)的恰好包含\(k\)枚棋子的子矩形个 ...

  5. 「CF526F」 Pudding Monsters

    CF526F Pudding Monsters 传送门 模型转换:对于一个 \(n\times n\) 的棋盘,若每行每列仅有一个棋子,令 \(a_x=y\),则 \(a\) 为一个排列. 转换成排列 ...

  6. Pudding Monsters CodeForces - 526F (分治, 双指针)

    大意: n*n棋盘, n个点有怪兽, 求有多少边长为k的正方形内恰好有k只怪兽, 输出k=1,...,n时的答案和. 等价于给定n排列, 对于任意一个长为$k$的区间, 若最大值最小值的差恰好为k, ...

  7. [Codeforce526F]:Pudding Monsters(分治)

    题目传送门 题目描述 由于各种原因,桐人现在被困在Under World(以下简称UW)中,而UW马上要迎来最终的压力测试——魔界入侵.唯一一个神一般存在的Administrator被消灭了,靠原本的 ...

  8. 奇袭 CodeForces 526F Pudding Monsters 题解

    考场上没有认真审题,没有看到该题目的特殊之处: 保证每一行和每一列都恰有一只军队,即每一个Xi和每一个Yi都是不一样 的. 于是无论如何也想不到复杂度小于$O(n^3)$的算法, 只好打一个二维前缀和 ...

  9. 【CF526F】Pudding Monsters

    题意: 给你一个排列pi,问你有对少个区间的值域段是连续的. n≤3e5 题解: bzoj3745

随机推荐

  1. linux 启动自动运行

    开机启动时自动运行程序  Linux    1.加载后, 它将初始化硬件和设备驱动, 然后运行第一个进程init.init根据配置文件继续引导过程,启动其它进程.通常情况下,修改放置在 /etc/rc ...

  2. 【转】利用telnet来进行调试Skynet

    https://blog.csdn.net/WhereIsHeroFrom/article/details/80674408

  3. 3星|《规避政治风险:全球化企业必修课》:中国将赢得5G竞争

    规避政治风险:全球化企业必修课(<哈佛商业评论>增刊) <哈佛商业评论>的两篇文章+<财经>的1篇文章.把<财经>的文章放到增刊中,好像是第一次,我觉得 ...

  4. MPVUE多环境定义后台URL

    小程序选定了mpvue作为开发框架,搭建开发环境和构建环境.自从用了Travis和Jenkins之后,再也回不到手工构建的时代了. 目的-自动构建 web项目中,自从前后台分离的结构形成,就形成了一个 ...

  5. Linux系统下搭建FTP/SFTP服务器

    传输文件经常使用ftp和sftp服务器.Windows下有多种可视化工具,使用快捷.Linux经常需要自行搭建这两种服务器,当然搭建熟练的话,会更加快捷. 1.检查Linux系统是否安装了vsftp和 ...

  6. 炸!分享美团面试关于selenium的面试题

    个人分类: 软件测试 编辑 在这个互联网技术快速迭代的时代,每个测试员都知道技术对于职业发展的重要性,那些技术好的测试员不仅薪资高,而且大多数集中在一线互联网企业工作,让人感觉非常高大上的同时,也想去 ...

  7. 使用python实现用微信远程控制电脑

    首先,我们要先看看微信远程控制电脑的原理是什么呢? 我们可以利用Python的标准库控制本机电脑,然后要实现远程的话,我们可以把电子邮件作为远程控制的渠道,我们用Python自动登录邮箱检测邮件,当我 ...

  8. Dao DaoImp

    DAO层:DAO层主要是做数据持久层的工作,负责与数据库进行联络的一些任务都封装在此,DAO层的设计首先是设计DAO的接口,然后在Spring的配置文件中定义此接口的实现类,然后就可在模块中调用此接口 ...

  9. 2017-2018-2 1723 『Java程序设计』课程 结对编程练习-四则运算-准备阶段

    2017-2018-2 1723 『Java程序设计』课程 结对编程练习-四则运算-准备阶段 在一个人孤身奋斗了将近半个学期以后,终于迎来的我们的第一次团队协作共同编码,也就是,我们的第一个结对编程练 ...

  10. servlet几个常用的方法

    servlet继承了HTTPServlet所以可以重写父类的方法,下面一 一介绍方法Dopost DoGet 比较常用不再介绍. 一.Init(),和Init(ServletConfig config ...