题传

先想一个巨 shaber 的暴力 DP:设 \(f_{i}\) 为对前 \(i\) 个人分段的最优解,则:

\[f_{i}=\max_{0\le j<i}\{f_{j}+\operatorname{W}(j+1, i)\}
\]

其中:

\[\operatorname{W}(x, y)=\sum_{i=x}^y [l_i \le \max(x_j|j\in [x, y]) \le r_i]
\]

暴力做显然是 \((n^2)\) 的,考虑优化。

如果考虑将决策中的 \(i\) 右移一位,用线段树维护 \(val_i(x)=f_{x-1}+\operatorname{W}(x, i)\) 的话,发现右移时无法快速修改有变化的位置(类似 \(+1\ 0\ 0\ +1\dots\) 状物,不好维护)。

正难则反,考虑某个 \(j\) 会对哪些决策位置 \((x, i)\) 有贡献。

我们将判断条件 \(\max(x_p | p \in [x, i])\) 拆成两部分: \(\max(x_p | p \in [x, j])\) 和 \(\max(x_p | p \in [j, i])\)。

不难画出下图:

先考虑 \(i\in [l2, r2]\),对于这一段位置,\(i\) 已经满足了 \(l_j \le \max(x_p | p \in [j, i]) \le r_j\),那么 \(x\) 只要在 \([R_j, j]\) 之间即可。

然后是 \(i\in [j, l2)\),此时 \(x\) 就必须满足 \(l_j \le \max(x_p | p \in [x, j]) \le r_j\),即 \(x \in [r1, l1]\)。

对于 \(i > r2\),显然 \(j\) 已经贡献不到了。

然后你就发现每个 \(j\) 贡献到的 \(i\) 是连续的,而且对于每个被贡献到的 \(i\),函数 \(\operatorname{W}\) 区间左端点 \(x\) 也是连续的。

所以我们在 \(j\) 处塞一个 \([r1, l1]\) 区间 +1 的操作,在 \(l2\) 处塞一个 \((l1, j]\) 区间 +1 的操作(\([r1, l1]\) 在前面已经被加过一次了)。

然后在 \(r2+1\) 的位置塞一个消除贡献的区间 -1 操作即可。

操作数显然是 \(O(n)\) 的,\(l1, l2, r1, r2\) 可以单调栈后二分找。

总复杂度 \(O(n\log n)\)。

Code

#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <cctype>
#include <vector>
#define st first
#define nd second
using namespace std;
typedef long long ll;
typedef pair <int, int> Pii;
const int INF=0x3f3f3f3f;
const int mo=1e9+7;
inline int read(){
char ch=getchar();int x=0, f=1;
while(!isdigit(ch)){if(ch=='-') f=-1; ch=getchar();}
while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
inline void write(int x){
if(x<0) putchar('-'), x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
inline int ksm(int a, int b){
int ret=1;
for(; b; b>>=1, a=1ll*a*a%mo)
if(b&1) ret=1ll*ret*a%mo;
return ret;
}
const int N=1e5+5;
namespace Segment{
#define ls k<<1
#define rs k<<1|1
#define mid (l+r>>1)
int Mx[N*4], tag[N*4];
void build(){
memset(Mx, -9, sizeof(Mx));
memset(tag, 0, sizeof(tag));
}
void upd(int k, int v){Mx[k]+=v, tag[k]+=v;}
void pushdown(int k){if(tag[k]) upd(ls, tag[k]), upd(rs, tag[k]), tag[k]=0;}
void pushup(int k){Mx[k]=max(Mx[ls], Mx[rs]);}
void change(int k, int l, int r, int x, int v){
if(l==r) return (void)(Mx[k]=max(Mx[k], v));pushdown(k);
if(x<=mid) change(ls, l, mid, x, v);
else change(rs, mid+1, r, x, v);
pushup(k);
}
void modify(int k, int l, int r, int x, int y, int v){
if(x>y) return ;//if(k==1) printf("make %d %d %d\n", x, y, v);
if(x<=l&&r<=y) return upd(k, v);pushdown(k);
if(x<=mid) modify(ls, l, mid, x, y, v);
if(mid<y) modify(rs, mid+1, r, x, y, v);
pushup(k);
}
#undef ls
#undef rs
#undef mid
}
int n, a[N], la[N], ra[N], f[N];
Pii L[N], R[N];
vector < pair<Pii, int> > op[N];
int sta[N], top=0;
int find(int x){
int l=1, r=top, ans=0;
while(l<=r){
int mid=l+r>>1;
if(a[sta[mid]]>=x) l=mid+1, ans=mid;
else r=mid-1;
}
return sta[ans];
}
signed main(){
n=read();
for(int i=1; i<=n; ++i) a[i]=read();
for(int i=1; i<=n; ++i) la[i]=read(), ra[i]=read();
top=0;
for(int i=1; i<=n; ++i){
while(top&&a[sta[top]]<a[i]) --top;
sta[++top]=i;L[i]=make_pair(find(la[i]), find(ra[i]+1)+1);
}
sta[top=0]=n+1;
for(int i=n; i>=1; --i){
while(top&&a[sta[top]]<a[i]) --top;
sta[++top]=i;R[i]=make_pair(find(la[i]), find(ra[i]+1));
// printf("(%d %d)\n", R[i].first, R[i].second-1);
}
for(int i=1; i<=n; ++i)
if(a[i]<=ra[i])
op[i].push_back(make_pair((Pii){L[i].nd, L[i].st}, 1)),
op[R[i].st].push_back(make_pair((Pii){L[i].st+1, i}, 1)),
op[R[i].nd].push_back(make_pair((Pii){L[i].nd, i}, -1));
int ans=0;Segment :: build();
for(int i=1; i<=n; ++i){
// printf("for %d\n", i);
Segment :: change(1, 1, n, i, f[i-1]);
for(auto x : op[i])
Segment :: modify(1, 1, n, x.st.st, x.st.nd, x.nd);
f[i]=Segment :: Mx[1];
// printf("find %d\n", f[i]);
ans=max(f[i], ans);
}
printf("%d\n", ans);
return 0;
}

Luogu P7503 「HMOI R1」文化课的更多相关文章

  1. 「POI2011 R1」Conspiracy

    「POI2011 R1」Conspiracy 解题思路 : 问题转化为,将点集分成两部分,其中一部分恰好组成一个团,其中另一部分恰好组成一个独立集. 观察发现,如果求出了一个解,那么答案最多可以在这个 ...

  2. [Luogu 3701] 「伪模板」主席树

    [Luogu 3701] 「伪模板」主席树 这是一道网络流,不是主席树,不是什么数据结构,而是网络流. 题目背景及描述都非常的暴力,以至于 Capella 在做此题的过程中不禁感到生命流逝. S 向 ...

  3. [Luogu] P3701 「伪模板」主席树

    题目背景 byx和手气君都非常都非常喜欢种树.有一天,他们得到了两颗奇怪的树种,于是各自取了一颗回家种树,并约定几年后比一比谁种出来的树更加牛x. 题目描述 很快,这棵树就开花结果了.byx和手气君惊 ...

  4. LuoguP7127 「RdOI R1」一次函数(function) 题解

    Content 设 \(S_k\) 为直线 \(f(x)=kx+k-1\),直线 \(f(x)=(k+1)x+k\) 与 \(x\) 轴围成的三角形的面积.现在给出 \(t\) 组询问,每组询问给定一 ...

  5. 「算法笔记」树形 DP

    一.树形 DP 基础 又是一篇鸽了好久的文章--以下面这道题为例,介绍一下树形 DP 的一般过程. POJ 2342 Anniversary party 题目大意:有一家公司要举行一个聚会,一共有 \ ...

  6. loj#2020 「AHOI / HNOI2017」礼物 ntt

    loj#2020 「AHOI / HNOI2017」礼物 链接 bzoj没\(letex\),差评 loj luogu 思路 最小化\(\sum\limits_1^n(a_i-b_i)^2\) 设改变 ...

  7. 「AHOI / HNOI2017」影魔

    「AHOI / HNOI2017」影魔 题目描述 解决这类比较复杂的区间贡献问题关键在于找到计算的对象. 比如这道题,我们计算的对象就是区间中间的最大值. 对于点\(i\),我们找到左边第一个比他大的 ...

  8. [LOJ 2022]「AHOI / HNOI2017」队长快跑

    [LOJ 2022]「AHOI / HNOI2017」队长快跑 链接 链接 题解 不难看出,除了影响到起点和终点的射线以外,射线的角度没有意义,因为如果一定要从该射线的射出一侧过去,必然会撞到射线 因 ...

  9. 「GXOI / GZOI2019」宝牌一大堆 (DP)

    题意 LOJ传送门 题解 可以发现「七对子」 和 「国士无双」直接暴力就行了. 唯一的就是剩下的"3*4+2". 考试的时候写了个爆搜剪枝,开了O2有50pts.写的时候发现可以D ...

  10. 「国家集训队」小Z的袜子

    「国家集训队」小Z的袜子 传送门 莫队板子题. 注意计算答案的时候,由于分子分母都要除以2,所以可以直接约掉,这样在开桶算的时候也方便一些. 参考代码: #include <algorithm& ...

随机推荐

  1. 【SpringCloud】SpringCloud Alibaba Seata处理分布式事务

    SpringCloud Alibaba Seata处理分布式事务 分布式事务问题 分布式前 单机库存没这个问题 O(∩_∩)O 从1:1->1:N->N:N 分布式之后 单体应用被拆分成微 ...

  2. spring项目使用EMQX,使用@Autowired注入失败报错空指针问题记录

    目录 java客户端使用MQTT订阅消息大致流程 MQTTConnect部分代码 MQTTListener部分代码 问题分析 问题原因 解决方法 总结 参考 java客户端使用MQTT订阅消息大致流程 ...

  3. kafka 基础入门

    kafka是什么 Kafka (Apache kafka is a distributed streaming platform) ,官方定义是一个分布式流式计算平台.在我开发的项目中,是把kafka ...

  4. 爬虫项目之爬取4K高清壁纸

    爬虫项目之爬取4K高清壁纸 目标网址:4K壁纸高清图片_电脑桌面手机全面屏壁纸4K超清_高清壁纸4K全屏 - 壁纸汇 使用技术Selenium+Requests 下面是目标网页 思路:由于此网页是通过 ...

  5. jmeter之请求体类型

    一.当post方法的提交数据类型(content-type)为multipart/form-data,请求体为文件文件上传. fiddler抓包请求体的name对应jmerter文件上传的参数名称,f ...

  6. Canvas上批量创建可视对象(DrawingVisual)管理,获取鼠标悬浮图形状态,并控制鼠标右键快捷菜单等...

    近期公司有个新的定制,先简要说明下: 窗口上有个播放区域,区域上悬浮了很多可视对象(DrawingVisual),全部是动态生成的.... 现在的需求是在这些矩形框上需要添加右键快捷菜单... 需求知 ...

  7. kubelet 创建 Pod 前发生了什么?

    Kubelet Watch 到新增的 Pod,需要做的主要有以下几件事: 管理 Pod 状态,除了更新本地缓存,还要同步给 API server 计算节点的资源是否足够创建 Pod 创建 Cgroup ...

  8. hadoop问题解决(七)日志/重启/开机自启动

    6.1hadoop日志 Master节点 Slave节点 6.2 hadoop排错 (待补充) 6.3 spark 6.4 zookeeper 6.5 hive 6.6 kafka 7重启命令 7.1 ...

  9. SpringIntegrationRamble

    目录 Why SpringIntegration Background Consolidate Architecture ESB service Popular Solutions Getting S ...

  10. 银河麒麟系统 jenkins docker 部署 自动化打包部署git 项目

    Jenkins 是一个开源的自动化服务器,主要用于实现 持续集成(CI) 和 持续交付/部署(CD),其核心作用在于通过自动化流程提升软件开发和交付的效率与质量 一.环境准备 1. 安装 Docker ...