CF526F Pudding Monsters

题目大意:给出一个\(n* n\)的棋盘,其中有\(n\)个格子包含棋子。

每行每列恰有一个棋子。

求\(k*k\)的恰好包含\(k\)枚棋子的子矩形个数。

比较有意思的一道分治题目.

首先我们将所有棋子归位

设\(sum_i\)表示第\(i\)行的棋子在第\(sum_i\)列

那么\(sum\)数组就一定是一个排列

而题目就可以转化为

这个排列中有多少个区间的值域是连续的

我们考虑分治解决,每次考虑夸\(mid\)的答案个数

我们提前预处理出\(mid\)为起点的向左后缀最值和向右前缀最值

分四种情况考虑,

1:最大值和最小值都在左边

我们可以直接根据最值求出\(r\)

\(r = l+max_l-min_l\)

在判断\(r\)是否合法即可.

2:最大值和最小值都在右边

我们可以直接根据最值求出\(l\)

\(l = r - (max_r-min_i)\)

3:最大值在左边最小值在右边

\(max_i-min_j=j - i\)

化一下变成了

\(max_i+i = min_j+j\)

就开一个桶记录所有合法的\(min_j+j\)每次查询\(max_i+i\),

我们想一下,对于左边的每一个\(i\),可能课他产生贡献的都是一个右边对应的一个区间

我们就用双指针维护这个东西

注意维护的时候先动右边的指针,再跟左边的指针即可

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

同上即可

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cctype>
#include<algorithm>
using namespace std;
const int N = 3e5 + 3;
struct node{
int xi;
int yi;
}a[N];
int n,m;
int c[N << 1];
struct th{
int maxx;
int minn;
};
th tl[N],tr[N];
int sum[N];
long long ans = 0;
inline bool cmp(node x,node y){
return x.xi < y.xi;
}
inline int read(){
int v = 0,c = 1;char ch = getchar();
while(!isdigit(ch)){
if(ch == '-') c = -1;
ch = getchar();
}
while(isdigit(ch)){
v = v * 10 + ch - 48;
ch = getchar();
}
return v * c;
}
inline void solve(int l,int r){
if(l == r) {ans++;return;}
int mid = (l + r) >> 1;
solve(l,mid);solve(mid + 1,r);
// printf("%d %d\n",l,r);
tl[mid].maxx = tl[mid].minn = a[mid].yi;
for(int i = mid - 1;i >= l;--i){
tl[i].maxx = max(tl[i + 1].maxx,a[i].yi);
tl[i].minn = min(tl[i + 1].minn,a[i].yi);
}
tr[mid + 1].maxx = tr[mid + 1].minn = a[mid + 1].yi;
for(int i = mid + 2;i <= r;++i){
tr[i].maxx = max(tr[i - 1].maxx,a[i].yi);
tr[i].minn = min(tr[i - 1].minn,a[i].yi);
}
// printf("lmin:");
// for(int i = mid;i >= l;--i) printf("%d ",tl[i].minn);puts("");
// printf("lmax:");
// for(int i = mid;i >= l;--i) printf("%d ",tl[i].maxx);puts("");
// printf("rmin:");
// for(int i = mid + 1;i <= r;++i) printf("%d ",tr[i].minn);puts("");
// printf("rmax:");
// for(int i = mid + 1;i <= r;++i) printf("%d ",tr[i].maxx);puts("");
// printf("ans0:%d\n",ans);
for(int i = mid;i >= l;--i){
int to = i + tl[i].maxx - tl[i].minn;
if(to <= mid || to > r) continue;
if(tr[to].maxx < tl[i].maxx && tr[to].minn > tl[i].minn) ans++;
}
// printf("ans1:%d\n",ans);
for(int i = mid + 1;i <= r;++i){
int to = i - (tr[i].maxx - tr[i].minn);
if(to >= mid + 1 || to < l) continue;
if(tl[to].maxx < tr[i].maxx && tr[i].minn < tl[to].minn) ans++;
}
// printf("ans2:%d\n",ans);
int ll = mid + 1,rr = mid + 1;
for(int i = mid;i >= l;--i){
// while(now <= r && tl[i].maxx > tr[now].maxx && tl[i].minn > tr[now].minn) {
// c[now + tr[now].minn]++;
// now++;
// }
while(rr <= r && tr[rr].maxx < tl[i].maxx) c[rr + tr[rr].minn]++,++rr;
while(ll < rr && tr[ll].minn > tl[i].minn) c[ll + tr[ll].minn]--,++ll;
// if(tl[i].maxx > tr[now - 1].maxx && tl[i].minn > tr[now - 1].minn)
ans += c[i + tl[i].maxx];
// while(now <= r && tr[now].minn > tl[i].minn) now++;
// while() }
// printf("ans3:%d\n",ans);
for(int i = ll;i < rr;++i) c[i + tr[i].minn]--;
//for(int i = 1;i <= 10000;++i) if(c[i] != 0) cout <<"GG";
// memset(c,0,sizeof(c));
ll = rr = mid;
//max in R,min in L
for(int i = mid + 1;i <= r;++i){
// while(now >= l && tr[i].maxx > tl[now].maxx && tr[i].minn > tl[now].minn){
// c[now - tl[now].minn + N]++;
// now--;
// // cout << i << " " << now << endl;
// }
// if(tr[i].maxx > tl[now + 1].maxx && tr[i].minn > tl[now + 1].minn)
// ans += c[i - tr[i].maxx + N];
// while(now >= l && tl[now].minn > tr[i].minn) now--;
while(ll >= l && tl[ll].maxx < tr[i].maxx) c[ll - tl[ll].minn + N]++,--ll;
while(rr > ll && tl[rr].minn > tr[i].minn) c[rr - tl[rr].minn + N]--,--rr;
ans += c[i - tr[i].maxx + N];
}
// memset(c,0,sizeof(c));
for(int i = rr;i > ll;--i) c[i - tl[i].minn + N]--;
// printf("ans4:%d\n",ans);
}
int main(){
n = read();
for(int i = 1;i <= n;++i) a[i].xi = read(),a[i].yi = read(),sum[a[i].xi] = a[i].yi;
for(int i = 1;i <= n;++i) a[i].yi = sum[i];
// for(int i = 1;i <= n;++i) printf("%d ",sum[i]);puts("");
solve(1,n);
cout << ans << endl;
return 0;
}

CF526F Pudding Monsters的更多相关文章

  1. 「CF526F」 Pudding Monsters

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

  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. [Codeforces526F]Pudding Monsters 分治

    F. Pudding Monsters time limit per test 2 seconds memory limit per test 256 megabytes In this proble ...

  5. CodeForces526F:Pudding Monsters (分治)

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

  6. 【CF526F】Pudding Monsters

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

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

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

  8. Codeforces 526F Pudding Monsters

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

  9. Codeforces 436D Pudding Monsters

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

随机推荐

  1. iOS 9适配

    iOS 9系统策略更新,请开发者注意升级 近期苹果公司iOS 9系统策略更新,限制了http协议的访问,此外应用需要在“Info.plist”中将要使用的URL Schemes列为白名单,才可正常检查 ...

  2. 探索云数据库最佳实践 阿里云开发者大会数据库专场邀你一起Code up!

    盛夏.魔都.科技 三者在一起有什么惊喜? 7月24日,阿里云峰会·上海——开发者大会将在上海世博中心盛大启程,与未来世界的开发者们分享数据库.云原生.开源大数据等领域的技术干货,共同探讨前沿科技趋势, ...

  3. PLAY2.6-SCALA(六) 异步处理结果

    1.创建异步的controller Play是一个自底向上的异步框架,play处理所有的request都是异步.非阻塞的.默认的方式是使用异步的controller.换句话说,contrller中的应 ...

  4. activemq入门demo

    创建maven工程,pom文件如下 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="ht ...

  5. bzoj4152 The Captain

    Description 给定平面上的n个点,定义(x1,y1)到(x2,y2)的费用为min(|x1-x2|,|y1-y2|),求从1号点走到n号点的最小费用. Input 第一行包含一个正整数n(2 ...

  6. C++第一次作业(循环语句的使用)

    一.知识点 循环结构 二.教学目的 掌握while和do...while循环语句在C++中的写法 三.教学内容 1.while语句 (1)执行顺序:先判断表达式(循环控制条件)的值,若表达式的值为tr ...

  7. Gym - 101480K_K - Kernel Knights (DFS)

    题意:有两队骑士各n人,每位骑士会挑战对方队伍的某一个位骑士. (可能相同) 要求找以一个区间s: 集合S中的骑士不会互相挑战. 每个集合外的骑士必定会被集合S内的某个骑士挑战. 题解:讲真被题目绕懵 ...

  8. css浮动规则

    1.浮动元素会从文档正常流中删除,但它仍会影响布局 2.浮动非替换元素必须为其指定width,否则元素的width会趋于0而导致浮动元素不能完整显示3.一旦元素具有了浮动属性,它便成为了一个块级元素. ...

  9. python 操作asdl

    #!/usr/bin/env python# -*- coding:utf-8 -*- import win32ras import time,os def Connect(dialname, acc ...

  10. part10.2-字符设备驱动模型