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 5
output
10

  题目大意 给定平面上有n个点,每行每列上只有一个点,问总共有多少个边长为k的矩形框住了k个点。

  刚开学,好久(也就两周)都没搞OI,差点不知OI为何物了。qaq。有人把这道题改题面拿给我们考试,然后考试时没想出正解,暴力分段90分。。于是班上出现了一群优秀的魔(膜)法师。

  显然,可以把它转化成序列上的问题(序列就是a[i]表示第i列上的点的纵坐标):有多少个长度为k的区间使得这一段的最大值和最小值之差等于k - 1。

  然后上CDQ分治进行瞎搞。记当前分治区间为[l, r],分治中心为mid,统计经过分治中心的子区间,分四种情况讨论:

  1)子区间的最大值和最小值同在左侧(相对于分治中心)

  2)子区间的最小值在左侧,最大值在右侧

  3)子区间的最大值和最小值同在右侧

  4)子区间的最大值在左侧,最小值在右侧

  由于情况1,3和2,4的做法类似,所以只考虑情况1,2

  情况1:

    记录左侧每个位置到分治中心的最大值和最小值。

    枚举子区间的左端点,可以根据记录的数据计算出右端点,如果合法(在分治中心右侧,并且最大值和最小值满足在左侧)就将答案加1.

  情况2:

    从分治中心向左枚举左端点i,考虑先使最值的条件合法。

    考虑到前后缀最大值和最小值都有不增或不减的单调性。所以设置两个"指针",r1和r2。

    r1是第一个使最大值在右侧的位置,r2是第一个使最小值不在左边的位置。那么左端点为i,右端点在整数区间[r1, r2)内的子区间都满足最值的限制。

    现在考虑如何统计答案。临时约定max[l, r]表示a[l],a[l + 1], ..., a[r]的最大值,同理定义min[l, r]。

    显然

    移一下项得到

    所以在挪动"指针"的时候把右边的一坨东东扔进某个桶里面就好了。挪动完成后根据当前枚举的左端点i,首先判断是否合法(比如什么r1大于等于r2的时候就continue就好了,如果合法的话就加上对应桶里的计数就好了。

    这种情况搞定了之后,不要忘记清空桶,由于桶可能很大,所以不要memset或者fill,for数组a就好了。

Code

 /**
* Codeforces
* Problem#526F
* Accepted
* Time: 140ms
* Memory: 8200k
*/
#include <iostream>
#include <fstream>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <cctype>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <stack>
#include <bitset>
#ifndef WIN32
#define Auto "%lld"
#else
#define Auto "%I64d"
#endif
using namespace std;
typedef bool boolean;
#define clra(a) memset(a, false, sizeof(a))
const signed int inf = ((~0u) >> );
#define smin(a, b) a = min(a, b)
#define smax(a, b) a = max(a, b)
#define LL long long const int N = 3e5; int n;
int *arr;
int *pmin, *pmax, *rmin, *rmax;
int bucket[(N << ) + ]; inline void init() {
scanf("%d", &n);
arr = new int[(n + )];
pmin = new int[(n + )];
pmax = new int[(n + )];
rmin = new int[(n + )];
rmax = new int[(n + )];
for(int i = , x, y; i <= n; i++) {
scanf("%d%d", &x, &y);
arr[x] = y;
}
} LL CDQDividing(int l, int r) {
if(l == r) return ; int mid = (l + r) >> ;
LL rt = ;
pmin[mid] = arr[mid], pmax[mid] = arr[mid], rmin[mid + ] = arr[mid + ], rmax[mid + ] = arr[mid + ];
for(int i = mid - ; i >= l; i--)
pmin[i] = min(pmin[i + ], arr[i]), pmax[i] = max(pmax[i + ], arr[i]);
for(int i = mid + ; i <= r; i++)
rmin[i] = min(rmin[i - ], arr[i]), rmax[i] = max(rmax[i - ], arr[i]); for(int i = l, rg; i <= mid; i++) {
rg = i + pmax[i] - pmin[i];
rt += rg > mid && rg <= r && rmax[rg] < pmax[i] && rmin[rg] > pmin[i];
}
for(int i = mid + , lf; i <= r; i++) {
lf = i - rmax[i] + rmin[i];
rt += lf <= mid && lf >= l && pmax[lf] < rmax[i] && pmin[lf] > rmin[i];
}
for(int i = mid, r1 = mid + , r2 = mid + ; i >= l && r1 <= r; i--) { // The min num is on the left.
while(r2 <= r && rmin[r2] > pmin[i]) bucket[r2 - rmax[r2] + N]++, r2++;
while(r1 <= r && rmax[r1] < pmax[i]) bucket[r1 - rmax[r1] + N]--, r1++;
if(r1 < r2) rt += bucket[i - pmin[i] + N];
}
for(int i = mid + ; i <= r; i++)
bucket[i - rmax[i] + N] = ;
// cout << rt << endl;
for(int i = mid + , l1 = mid, l2 = mid; i <= r && l2 >= l; i++) { // The min num is on the right.
while(l1 >= l && pmin[l1] > rmin[i]) bucket[l1 + pmax[l1]]++, l1--;
while(l2 >= l && pmax[l2] < rmax[i]) bucket[l2 + pmax[l2]]--, l2--;
if(l1 < l2) rt += bucket[i + rmin[i]];
}
for(int i = l; i <= mid; i++)
bucket[i + pmax[i]] = ; return rt + CDQDividing(l, mid) + CDQDividing(mid + , r);
} inline void solve() {
printf(Auto, CDQDividing(, n));
} int main() {
init();
solve();
return ;
}

Codeforces 526F Pudding Monsters - CDQ分治 - 桶排序的更多相关文章

  1. 【CF526F】Pudding Monsters cdq分治

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

  2. 奇袭 CodeForces 526F Pudding Monsters 题解

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

  3. Codeforces 526F Pudding Monsters

    先把题目抽象一下: 有一个静态的数组,求有多少个区间[i,j]满足:j-i==max{ai,...,aj}-min{ai,...,aj} 也就是要求max-min+i-j==0的区间数 所以肿么做呢? ...

  4. Codeforces 1045G AI robots [CDQ分治]

    洛谷 Codeforces 简单的CDQ分治题. 由于对话要求互相看见,无法简单地用树套树切掉,考虑CDQ分治. 按视野从大到小排序,这样只要右边能看见左边就可以保证互相看见. 发现\(K\)固定,那 ...

  5. Codeforces 848C Goodbye Souvenir [CDQ分治,二维数点]

    洛谷 Codeforces 这题我写了四种做法-- 思路 不管做法怎样,思路都是一样的. 好吧,其实不一样,有细微的差别. 第一种 考虑位置\(x\)对区间\([l,r]\)有\(\pm x\)的贡献 ...

  6. CodeForces526F:Pudding Monsters (分治)

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

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

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

  8. Codeforces 436D - Pudding Monsters(dp)

    Codeforces 题目传送门 & 洛谷题目传送门 u1s1 这题数据范围有点迷惑啊--乍一看 \(\mathcal O(nm)\) 过不去,还以为是正解是 \(\mathcal O(n+m ...

  9. Codeforces 436D Pudding Monsters

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

随机推荐

  1. cocos2d 利用cocosStudio制作合图(plist与png)

  2. (已解决)Xcode 运行cocos2dx弹出内部错误对话框(Internal Error)

    cocos2dx未捕获的异常升高.选择“继续”继续运行在一个不一致的状态.选择“崩溃”停止应用和崩溃报告一个错误文件. 莫名其妙,代码没有报错,运行时却弹出(内部错误)对话框出来: 再看看崩溃的底层代 ...

  3. node.js初识12

    1.express框架属于后端的框架 cnpm install --save express --save的作用是将下载的保存在package.json中 你可以点击http://www.expres ...

  4. JavaScript 字符串replace全局替换

    一般使用replace let str = "2018-8-14"; str.replace('-','/')//2018/8-14 并没有替换第二个”-“, 所以我们用正则表达式 ...

  5. c3p0:Connections could not be acquired from the underlying database!解决方案

    在利用ssh框架做网站的时候遇到了一个比较棘手的问题,一直连接不上数据库,问题描述如下: 各种百度然后说的最多的解决方案是: 1,驱动配置有误:2,数据库连接地址有误:3,密码或帐号有误: 4,数据库 ...

  6. Yii2返回以主键id为键名的数组

    branch.php <?php namespace app\models; use Yii; /** * This is the model class for table "bra ...

  7. jQuery样式--css(name|pro|[,val|fn])

    css(name|pro|[,val|fn]) 概述 访问匹配元素的样式属性 参数 name  要访问的属性名称 name  一个或多个CSS属性组成的一个数组 properties  要设置为样式属 ...

  8. mitmproxy 中间人攻击的小玩笑

    import mitmproxy.http from mitmproxy import ctx, http class Joker: def request(self, flow: mitmproxy ...

  9. MongoDB With Spark遇到的2个错误,不能初始化和sample重复的key

    1.$sample stage could not find a non-duplicate document while using a random cursor 这个问题比较难解决,因为我用mo ...

  10. Linux基础命令---添加组groupadd、删除组groupdel

    groupadd 指定群组名称来建立新的群组账号,需要时可以从系统中取得新的群组值. 此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS.SUSE.openSUSE.Fedora. ...