#分治 or 线段树+单调栈#CF526F Pudding Monsters
题目
给定一个 \(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的更多相关文章
- Codeforces 1175F - The Number of Subpermutations(线段树+单调栈+双针/分治+启发式优化)
Codeforces 题面传送门 & 洛谷题面传送门 由于这场的 G 是道毒瘤题,蒟蒻切不动就只好来把这场的 F 水掉了 看到这样的设问没人想到这道题吗?那我就来发篇线段树+单调栈的做法. 首 ...
- Codeforces 781E Andryusha and Nervous Barriers 线段树 单调栈
原文链接https://www.cnblogs.com/zhouzhendong/p/CF781E.html 题目传送门 - CF781E 题意 有一个矩形,宽为 w ,高为 h .一开始会有 w 个 ...
- 洛谷P4425 转盘 [HNOI/AHOI2018] 线段树+单调栈
正解:线段树+单调栈 解题报告: 传送门! 1551又是一道灵巧连题意都麻油看懂的题,,,,所以先解释一下题意好了,,,, 给定一个n元环 可以从0时刻开始从任一位置出发 每次可以选择向前走一步或者在 ...
- 线段树+单调栈+前缀和--2019icpc南昌网络赛I
线段树+单调栈+前缀和--2019icpc南昌网络赛I Alice has a magic array. She suggests that the value of a interval is eq ...
- 牛客多校第四场sequence C (线段树+单调栈)
牛客多校第四场sequence C (线段树+单调栈) 传送门:https://ac.nowcoder.com/acm/contest/884/C 题意: 求一个$\max {1 \leq l \le ...
- 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< ...
- AtCoder Regular Contest 063 F : Snuke’s Coloring 2 (线段树 + 单调栈)
题意 小 \(\mathrm{C}\) 很喜欢二维染色问题,这天他拿来了一个 \(w × h\) 的二维平面 , 初始时均为白色 . 然后他在上面设置了 \(n\) 个关键点 \((X_i , Y_i ...
- [Codeforces1132G]Greedy Subsequences——线段树+单调栈
题目链接: Codeforces1132G 题目大意:给定一个序列$a$,定义它的最长贪心严格上升子序列为$b$满足若$a_{i}$在$b$中则$a_{i}$之后第一个比它大的也在$b$中.给出一个数 ...
- BZOJ.4540.[HNOI2016]序列(莫队/前缀和/线段树 单调栈 RMQ)
BZOJ 洛谷 ST表的一二维顺序一定要改过来. 改了就rank1了哈哈哈哈.自带小常数没办法. \(Description\) 给定长为\(n\)的序列\(A_i\).\(q\)次询问,每次给定\( ...
- 2018.09.22 atcoder Snuke's Coloring 2(线段树+单调栈)
传送门 就是给出一个矩形,上面有一些点,让你找出一个周长最大的矩形,满足没有一个点在矩形中. 这个题很有意思. 考虑到答案一定会穿过中线. 于是我们可以把点分到中线两边. 先想想暴力如何解决. 显然就 ...
随机推荐
- String--cannot convert from 'const char *' to 'LPTSTR'错误
这种错误,很多情况下是类型不匹配 LPTSTR表示为指向常量TCHAR字符串的长指针 TCHAR可以是wchar_t或char,基于项目是多字节还是宽字节版本. 看下面的代码,代码来源:Example ...
- cookie和服务器Session的区别
cookie和服务器Session的区别 cookie和服务器Session都可用来存储用户信息,cookie存放于客户端,Session存放于web服务器端. 因为cookie存放于客户端有可能被窃 ...
- E4X已经被废弃,各浏览器基本上不再支持它;
E4X是一种在ECMAScript标准的基础上加入的动态XML支持的程序语言扩展. 到2019年,目前主流浏览器已经不太支持它了,一些版本的Firefox浏览器或许还可以使用,但它已经在主流浏览器的主 ...
- django学习第八天--多表操作删除和修改,子查询连表查询,双下划线跨表查询,聚合查询,分组查询,F查询,Q查询
orm多条操作 删除和修改 修改 在一对一和一对多关系时,和单表操作是一样的 一对一 一个作者对应一个信息 ad_obj = models.AuthorDetail.objects.get(id=1) ...
- iOS 面向对象与类
至于未来会怎样,要走下去才知道反正路还很长,天总会亮. 1. 面向对象 1.1 什么是面向对象(OOP) 面向对象 Object Oriented Programming.在软件开发中,我们虽然用的是 ...
- 带你领略下iOS中OC的“alloc”源代码,让你在工作中不在迷惑
前言 前面我们使用官方开源的objc源码进行了编译调试 objc4-818.2源码编译调试笔记 前言为什么会想要调试源码? 苹果开源了部分源码, 但相似内容太多, 基本找不到代码见的对应关系, 如果能 ...
- ElkStack-MACOS搭建
目录 简介 Elasticsearch Logstash/Filebeats Kibana 架构流程 安装配置 版本 先决条件 brew Elasticsearch mac安装elasticsearc ...
- 【Azure Fabric Service】Service Fabric 托管群集通过 Connect-ServiceFabricCluster 连接时候报错 CertificatedNotMatched
问题描述 Service Fabric 托管群集, 使用Key Vault中证书,把证书导入到本地安装后,使用该证书的 Thumbprint 作为指令 Connect-ServiceFabricClu ...
- 【Azure 应用服务】Azure Function 不能被触发
问题描述 Azure Function 不能被Postman 触发,错误信息如下: Error: write EPROTO 4020778632:error:100000f7:SSL routines ...
- Anaconda与Python环境在Windows中的部署
本文介绍在Win10电脑中,安装Anaconda环境与Python语言的方法. 在这里需要注意,本文介绍的方法是在电脑自身原本不含有Python的情况下进行的:如果大家电脑中原本就下载.安装过 ...