题目

给定一个 \(n \times n\) 的棋盘,其中有 \(n\) 个棋子,每行每列恰好有一个棋子。

求有多少个 \(k \times k\) 的子棋盘中恰好有 \(k\) 个棋子。


分析

先将二维的棋子转换成一维的排列,也就是问有多少个区间 \([l,r]\) 满足 \(\max-\min=r-l\)

一种方法就是分治,分类讨论最大值最小值在哪边,同一边那么另外一个端点就可以确定,

否则用一个桶记录一下 \(\max-r\) 或者 \(\max+l\) 的个数,把不合法的删掉,这样就是一个 \(\log\)

另外一种方法是固定右端点,然后用单调栈维护后缀最大值和最小值并在线段树上实时修改,

观察到 \(\max-\min+l\geq r\),并且在 \(l=r\) 时必取得最小值 \(r\),那么也就是询问最小值个数,同样在线段树上维护,也是一个 \(\log\)


代码(分治)

#include <cstdio>
#include <cctype>
using namespace std;
const int N=300011; long long ans;
int mn[N],mx[N],a[N],n,c[N<<1];
int iut(){
int ans=0; char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans;
}
int min(int x,int y){return x<y?x:y;}
int max(int x,int y){return x>y?x:y;}
void dfs(int l,int r){
if (l==r) return;
int mid=(l+r)>>1;
mn[mid]=mx[mid]=a[mid];
mn[mid+1]=mx[mid+1]=a[mid+1];
for (int i=mid-1;i>=l;--i) mn[i]=min(mn[i+1],a[i]),mx[i]=max(mx[i+1],a[i]);
for (int i=mid+2;i<=r;++i) mn[i]=min(mn[i-1],a[i]),mx[i]=max(mx[i-1],a[i]);
for (int i=mid;i>=l;--i){
int j=mx[i]-mn[i]+i;
if (j>mid&&j<=r&&mx[i]>mx[j]&&mn[j]>mn[i]) ++ans;
}
for (int j=mid+1;j<=r;++j){
int i=j-mx[j]+mn[j];
if (l<=i&&i<=mid&&mn[i]>mn[j]&&mx[j]>mx[i]) ++ans;
}
int j=mid+1,k=mid+1;
for (int i=mid;i>=l;--i){
for (;j<=r&&mn[j]>mn[i];++j) ++c[mx[j]-j+n];
for (;k<j&&mx[k]<mx[i];++k) --c[mx[k]-k+n];
ans+=c[mn[i]-i+n];
}
for (int i=k;i<j;++i) --c[mx[i]-i+n];
j=mid+1,k=mid+1;
for (int i=mid;i>=l;--i){
for (;j<=r&&mx[j]<mx[i];++j) ++c[mn[j]+j];
for (;k<j&&mn[k]>mn[i];++k) --c[mn[k]+k];
ans+=c[mx[i]+i];
}
for (int i=k;i<j;++i) --c[mn[i]+i];
dfs(l,mid),dfs(mid+1,r);
}
int main(){
n=iut();
for (int i=1,x;i<=n;++i)
x=iut(),a[x]=iut();
dfs(1,n);
return !printf("%lld",ans+n);
}

代码(线段树)

#include <cstdio>
#include <cctype>
using namespace std;
const int N=300011,inf=0x3f3f3f3f; long long ans;
int st0[N],st1[N],Top0,Top1,w[N<<2],mn[N<<2],lazy[N<<2],n,a[N];
int iut(){
int ans=0; char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans;
}
void build(int k,int l,int r){
mn[k]=inf,w[k]=r-l+1;
if (l==r) return;
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
}
void update(int k,int l,int r,int x,int y,int z){
if (l==x&&r==y){
mn[k]+=z,lazy[k]+=z;
return;
}
int mid=(l+r)>>1;
if (lazy[k]){
mn[k<<1]+=lazy[k],mn[k<<1|1]+=lazy[k];
lazy[k<<1]+=lazy[k],lazy[k<<1|1]+=lazy[k];
lazy[k]=0;
}
if (y<=mid) update(k<<1,l,mid,x,y,z);
else if (x>mid) update(k<<1|1,mid+1,r,x,y,z);
else update(k<<1,l,mid,x,mid,z),update(k<<1|1,mid+1,r,mid+1,y,z);
if (mn[k<<1]<mn[k<<1|1]) mn[k]=mn[k<<1],w[k]=w[k<<1];
else mn[k]=mn[k<<1|1],w[k]=w[k<<1|1]+(mn[k<<1]==mn[k<<1|1])*w[k<<1];
}
int main(){
n=iut();
for (int i=1,x;i<=n;++i) x=iut(),a[x]=iut();
build(1,1,n);
for (int i=1;i<=n;++i){
for (;Top0&&a[st0[Top0]]<=a[i];--Top0)
update(1,1,n,st0[Top0-1]+1,st0[Top0],a[i]-a[st0[Top0]]);
for (;Top1&&a[st1[Top1]]>=a[i];--Top1)
update(1,1,n,st1[Top1-1]+1,st1[Top1],a[st1[Top1]]-a[i]);
st0[++Top0]=st1[++Top1]=i,update(1,1,n,i,i,i-inf);
ans+=w[1];
}
return !printf("%lld",ans);
}

#分治 or 线段树+单调栈#CF526F Pudding Monsters的更多相关文章

  1. Codeforces 1175F - The Number of Subpermutations(线段树+单调栈+双针/分治+启发式优化)

    Codeforces 题面传送门 & 洛谷题面传送门 由于这场的 G 是道毒瘤题,蒟蒻切不动就只好来把这场的 F 水掉了 看到这样的设问没人想到这道题吗?那我就来发篇线段树+单调栈的做法. 首 ...

  2. Codeforces 781E Andryusha and Nervous Barriers 线段树 单调栈

    原文链接https://www.cnblogs.com/zhouzhendong/p/CF781E.html 题目传送门 - CF781E 题意 有一个矩形,宽为 w ,高为 h .一开始会有 w 个 ...

  3. 洛谷P4425 转盘 [HNOI/AHOI2018] 线段树+单调栈

    正解:线段树+单调栈 解题报告: 传送门! 1551又是一道灵巧连题意都麻油看懂的题,,,,所以先解释一下题意好了,,,, 给定一个n元环 可以从0时刻开始从任一位置出发 每次可以选择向前走一步或者在 ...

  4. 线段树+单调栈+前缀和--2019icpc南昌网络赛I

    线段树+单调栈+前缀和--2019icpc南昌网络赛I Alice has a magic array. She suggests that the value of a interval is eq ...

  5. 牛客多校第四场sequence C (线段树+单调栈)

    牛客多校第四场sequence C (线段树+单调栈) 传送门:https://ac.nowcoder.com/acm/contest/884/C 题意: 求一个$\max {1 \leq l \le ...

  6. cdqz2017-test10-rehearsal(CDQ分治&可持久化线段树&单调栈)

    题意: 给出n个三元组 e[i]=(si,ti,wi) 第i个三元组的价值为 Σ w[j] ,j 满足以下4个条件: 1.j<i 2.tj<ti 3.sj<si 4.不存在j< ...

  7. AtCoder Regular Contest 063 F : Snuke’s Coloring 2 (线段树 + 单调栈)

    题意 小 \(\mathrm{C}\) 很喜欢二维染色问题,这天他拿来了一个 \(w × h\) 的二维平面 , 初始时均为白色 . 然后他在上面设置了 \(n\) 个关键点 \((X_i , Y_i ...

  8. [Codeforces1132G]Greedy Subsequences——线段树+单调栈

    题目链接: Codeforces1132G 题目大意:给定一个序列$a$,定义它的最长贪心严格上升子序列为$b$满足若$a_{i}$在$b$中则$a_{i}$之后第一个比它大的也在$b$中.给出一个数 ...

  9. BZOJ.4540.[HNOI2016]序列(莫队/前缀和/线段树 单调栈 RMQ)

    BZOJ 洛谷 ST表的一二维顺序一定要改过来. 改了就rank1了哈哈哈哈.自带小常数没办法. \(Description\) 给定长为\(n\)的序列\(A_i\).\(q\)次询问,每次给定\( ...

  10. 2018.09.22 atcoder Snuke's Coloring 2(线段树+单调栈)

    传送门 就是给出一个矩形,上面有一些点,让你找出一个周长最大的矩形,满足没有一个点在矩形中. 这个题很有意思. 考虑到答案一定会穿过中线. 于是我们可以把点分到中线两边. 先想想暴力如何解决. 显然就 ...

随机推荐

  1. go经典知识及总结

    1.无论sync.Mutex还是其衍生品都会提示不能复制,但是能够编译运行 加锁后复制变量,会将锁的状态也复制,所以 mu1 其实是已经加锁状态,再加锁会死锁. 所以此题的答案是 fatal erro ...

  2. 团队协作如何确保项目Node版本的一致性?

    前言 想必大家在工作过程中都遇到过node版本带来的各种各样的问题,对于团队协作项目,你不能保证所有人的本地node版本都相同,所以在项目文档中往往会写上以下内容: 为与线上环境一致,请保证以下版本 ...

  3. 【Android 逆向】VM Kali 中 charles 抓android https 协议

    1. 虚拟机调成桥接模式(不用选择 复制物理网络链接状态) 2. 虚拟机中 打开 Charles 4. 选择 Proxy ->SSL Proxying Settings 1. 选择SSL Pro ...

  4. Lua学习笔记之迭代器、table、模块和包、元表和协程

    迭代器 迭代器是一种对象,它能够来遍历标准库模板容器中的部分或全部元素,每个迭代器对象代表容器中确定的地址,在Lua中迭代器是一种支持指针类型的结构,他可以遍历集合的每一个元素. 泛型for迭代器 泛 ...

  5. RK3568开发笔记(二):入手RK3568开发板的套件介绍、底板介绍和外设测试

    前言   本篇主要介绍RK3568芯片和入手开发板的底板介绍以及开发板的外设.   开发板   笔者的开发板是全套+10.1寸屏. 开发板实物     开发板资源    开发版本提供资料     开发 ...

  6. Kotlin 协程二 —— 通道 Channel

    目录 一. Channel 基本使用 1.1 Channel 的概念 1.2 Channel 的简单使用 1.3 Channel 的迭代 1.4 close 关闭 Channel 1.5 Channe ...

  7. chrome浏览器配置自定义搜索引擎

    chrome谷歌浏览器配置自定义搜索引擎 放弃百度搜索已经酝酿许久,现在搜索结果简直不忍直视.如果你想放弃使用百度搜索,并转向其他搜索引擎,头条搜索可能是一个不错的选择. 使用以下方式可以丝滑的使用其 ...

  8. 软件icon制作流程,就一张256-256的图即可,一键生成windows所有格式

    软件icon制作流程,就一张256-256的图即可,一键生成windows所有格式 好久不用这个都有些生疏了,还特意做了好几个尺寸的图,结果白弄了,软件会自动生成. 1.准备256-256px的图 2 ...

  9. Nginx配置https 之 找不到 ./configure

    Nginx配置https 之 找不到 ./configure 需求 要配置个https 问题 找不到文件在哪里 教程很简单,发现就是找不到 ./configure 这个文件 这个文件是 安装包的文件, ...

  10. STM32 SPI接口 DMA normal 和circual区别

    DMA有normal和circular两种模式. circular模式: 就调用这个函数一次就可以了,DMA一直开启,一帧数据发送完毕之后里面发送下一帧,中间没有停顿.这样确实是快了,也释放了CPU, ...