CF997E Good Subsegments

传送门

和 CF526F 差不多,只不过这道题是对多个子区间进行询问。

据说有一个叫析合树的东西可以在线做,不过有时间再说吧。

考虑离线询问,将每个询问固定至其右端点。

则我们要做的是在那道题的基础上,记录每个位置的历史贡献。

由于 \((i,i)\) 这个区间一直是符合条件的,故线段树根节点的最小值一定为 \(0\) ,我们只需要另外再维护一个标记,每次判断其是否与父节点的最小值一样即可。

贴代码

/*---Author:HenryHuang---*/
/*---Never Settle---*/
#include<bits/stdc++.h>
using namespace std;
const int maxn=1.2e5+5;
int val[maxn];
int num[maxn<<2],tot[maxn<<2],tag[maxn<<2],tt[maxn<<2];
long long sum[maxn<<2];
void up(int t){
num[t]=min(num[t<<1],num[t<<1|1]);tot[t]=0;
if(num[t]==num[t<<1]) tot[t]+=tot[t<<1];
if(num[t]==num[t<<1|1]) tot[t]+=tot[t<<1|1];
sum[t]=sum[t<<1]+sum[t<<1|1];
return ;
}
void down(int t){
if(tag[t]){
num[t<<1]+=tag[t],num[t<<1|1]+=tag[t];
tag[t<<1]+=tag[t],tag[t<<1|1]+=tag[t];
tag[t]=0;
}
if(tt[t]){
if(num[t<<1]==num[t]) sum[t<<1]+=1ll*tot[t<<1]*tt[t],tt[t<<1]+=tt[t];
if(num[t<<1|1]==num[t]) sum[t<<1|1]+=1ll*tot[t<<1|1]*tt[t],tt[t<<1|1]+=tt[t];
tt[t]=0;
}
}
void build(int l,int r,int t){
if(l==r){
num[t]=tot[t]=1;
return ;
}
int mid=(l+r)>>1;
build(l,mid,t<<1);
build(mid+1,r,t<<1|1);
up(t);return ;
}
void update(int ll,int rr,int l,int r,int nu,int t){
if(ll<=l&&r<=rr){
tag[t]+=nu;
num[t]+=nu;
return ;
}
int mid=(l+r)>>1;down(t);
if(ll<=mid) update(ll,rr,l,mid,nu,t<<1);
if(rr>mid) update(ll,rr,mid+1,r,nu,t<<1|1);
up(t);return ;
}
long long query(int ll,int rr,int l,int r,int t){
if(ll<=l&&r<=rr){
return sum[t];
}
int mid=(l+r)>>1;down(t);long long tmp=0;
if(ll<=mid) tmp+=query(ll,rr,l,mid,t<<1);
if(rr>mid) tmp+=query(ll,rr,mid+1,r,t<<1|1);
return tmp;
}
stack<pair<int,int> > mn,mx;
long long ans[maxn];
vector<pair<int,int> > opt[maxn];
int owo[maxn];
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
int n;cin>>n;
for(int i=1;i<=n;++i){
int b;cin>>b;
val[i]=b;
}
int Q;cin>>Q;
for(int i=1;i<=Q;++i){
int l,r;cin>>l>>r;
opt[r].emplace_back(l,i);
}
mx.emplace(0,2e9),mn.emplace(0,0);
build(1,n,1);
for(int i=1;i<=n;++i){
int p,q;
while((!mx.empty())&&mx.top().second<=val[i]){
tie(p,q)=mx.top();mx.pop();
update(mx.top().first+1,p,1,n,val[i]-q,1);
}
mx.emplace(i,val[i]);
while((!mn.empty())&&mn.top().second>=val[i]){
tie(p,q)=mn.top();mn.pop();
update(mn.top().first+1,p,1,n,q-val[i],1);
}
mn.emplace(i,val[i]);
update(1,i,1,n,-1,1);//[i,i]一定合法
++tt[1],sum[1]+=tot[1];
for(auto x:opt[i]){
tie(p,q)=x;
ans[q]+=query(p,i,1,n,1);
}
}
for(int i=1;i<=Q;++i) cout<<ans[i]<<'\n';
return 0;
}

「CF997E」 Good Subsegments的更多相关文章

  1. 「译」JUnit 5 系列:条件测试

    原文地址:http://blog.codefx.org/libraries/junit-5-conditions/ 原文日期:08, May, 2016 译文首发:Linesh 的博客:「译」JUni ...

  2. 「译」JUnit 5 系列:扩展模型(Extension Model)

    原文地址:http://blog.codefx.org/design/architecture/junit-5-extension-model/ 原文日期:11, Apr, 2016 译文首发:Lin ...

  3. JavaScript OOP 之「创建对象」

    工厂模式 工厂模式是软件工程领域一种广为人知的设计模式,这种模式抽象了创建具体对象的过程.工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题. function createPers ...

  4. 「C++」理解智能指针

    维基百科上面对于「智能指针」是这样描述的: 智能指针(英语:Smart pointer)是一种抽象的数据类型.在程序设计中,它通常是经由类型模板(class template)来实做,借由模板(tem ...

  5. 「JavaScript」四种跨域方式详解

    超详细并且带 Demo 的 JavaScript 跨域指南来了! 本文基于你了解 JavaScript 的同源策略,并且了解使用跨域跨域的理由. 1. JSONP 首先要介绍的跨域方法必然是 JSON ...

  6. 「2014-5-31」Z-Stack - Modification of Zigbee Device Object for better network access management

    写一份赏心悦目的工程文档,是很困难的事情.若想写得完善,不仅得用对工具(use the right tools),注重文笔,还得投入大把时间,真心是一件难度颇高的事情.但,若是真写好了,也是善莫大焉: ...

  7. 「2014-3-18」multi-pattern string match using aho-corasick

    我是擅(倾)长(向)把一篇文章写成杂文的.毕竟,写博客记录生活点滴,比不得发 paper,要求字斟句酌八股结构到位:风格偏杂文一点,也是没人拒稿的.这么说来,arxiv 就好比是 paper 世界的博 ...

  8. 「2014-3-17」C pointer again …

    记录一个比较基础的东东-- C 语言的指针,一直让人又爱又恨,爱它的人觉得它既灵活又强大,恨它的人觉得它太过于灵活太过于强大以至于容易将人绕晕.最早接触 C 语言,还是在刚进入大学的时候,算起来有好些 ...

  9. 「2014-3-13」Javascript Engine, Java VM, Python interpreter, PyPy – a glance

    提要: url anchor (ajax) => javascript engine (1~4 articles) => java VM vs. python interpreter =& ...

随机推荐

  1. 揭秘有状态服务上 Kubernetes 的核心技术

    背景 随着 Kubernetes 成为云原生的最热门的解决方案,越来越多的传统服务从虚拟机.物理机迁移到 Kubernetes,各云厂商如腾讯自研上云也主推业务通过Kubernetes来部署服务,享受 ...

  2. 基于OpenSeq2Seq的NLP与语音识别混合精度训练

    基于OpenSeq2Seq的NLP与语音识别混合精度训练 Mixed Precision Training for NLP and Speech Recognition with OpenSeq2Se ...

  3. Centos7拓展磁盘(逻辑增加)

    目录 第一步 第二步 第三步 以107.4G的Centos操作系统拓展20G磁盘空间,并将此20G磁盘空间分别分配给/home为例. 第一步 首先查看操作系统分区状况和磁盘占用情况.发现磁盘sda空间 ...

  4. 【SQLite】SQLite文件突然变大怎么办?瘦身办法

    使用VACUUM命令即可: VACUUM 命令通过复制主数据库中的内容到一个临时数据库文件,然后清空主数据库,并从副本中重新载入原始的数据库文件.这消除了空闲页,把表中的数据排列为连续的,另外会清理数 ...

  5. Spring FactoryBean和BeanFactory 区别

    1 BeanFactory 是ioc容器的底层实现接口,是ApplicationContext 顶级接口 spring不允许我们直接操作 BeanFactory  bean工厂,所以为我们提供了App ...

  6. C#中怎样使控件随着窗体一起变化大小

    此文原作者为CSDN的 zhouwen5288,原文链接  http://blog.csdn.net/zhouwen5288/article/details/6493835 本人仅作为随笔备忘,转载请 ...

  7. org.junit.Assert(断言)

    org.junit.Assert(断言) Assert是断言的意思,可以理解为"猜测",如果猜测错误,则抛出java.lang.AssertionError异常.  引入jar包  ...

  8. Vue.js的基础学习

    Vue.js的基础网上很多,这里不记录 开始正式页面的开发 1.页面加载时请求数据 methods: { post() { //发送post请求 this.$http.post('../../ashx ...

  9. 手把手教你实现一个支持插件化的 uTools 工具箱(一)

    前言 对于前端同学来说,我们会经常用到各种小工具,比如:图床.颜色拾取.二维码生成器.url 管理.文本比对.json 格式化.当然我们可以 chrome 收藏夹来管理各种在线的小工具,但作为一个有追 ...

  10. 阿里云中quick bi用地图分析数据时维度需转换为地理区域类型

    1.到数据集里面点击编辑要做地图分析的数据集 2.找到要分析的地理维度字段,选择转换为对应的类型,这里为市级,所以选择转换为市,其它类似,然后点击右上角保存即可. 3.返回数据集,点击新建仪表板 4. ...