Luogu P7503 「HMOI R1」文化课
先想一个巨 shaber 的暴力 DP:设 \(f_{i}\) 为对前 \(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」文化课的更多相关文章
- 「POI2011 R1」Conspiracy
「POI2011 R1」Conspiracy 解题思路 : 问题转化为,将点集分成两部分,其中一部分恰好组成一个团,其中另一部分恰好组成一个独立集. 观察发现,如果求出了一个解,那么答案最多可以在这个 ...
- [Luogu 3701] 「伪模板」主席树
[Luogu 3701] 「伪模板」主席树 这是一道网络流,不是主席树,不是什么数据结构,而是网络流. 题目背景及描述都非常的暴力,以至于 Capella 在做此题的过程中不禁感到生命流逝. S 向 ...
- [Luogu] P3701 「伪模板」主席树
题目背景 byx和手气君都非常都非常喜欢种树.有一天,他们得到了两颗奇怪的树种,于是各自取了一颗回家种树,并约定几年后比一比谁种出来的树更加牛x. 题目描述 很快,这棵树就开花结果了.byx和手气君惊 ...
- LuoguP7127 「RdOI R1」一次函数(function) 题解
Content 设 \(S_k\) 为直线 \(f(x)=kx+k-1\),直线 \(f(x)=(k+1)x+k\) 与 \(x\) 轴围成的三角形的面积.现在给出 \(t\) 组询问,每组询问给定一 ...
- 「算法笔记」树形 DP
一.树形 DP 基础 又是一篇鸽了好久的文章--以下面这道题为例,介绍一下树形 DP 的一般过程. POJ 2342 Anniversary party 题目大意:有一家公司要举行一个聚会,一共有 \ ...
- loj#2020 「AHOI / HNOI2017」礼物 ntt
loj#2020 「AHOI / HNOI2017」礼物 链接 bzoj没\(letex\),差评 loj luogu 思路 最小化\(\sum\limits_1^n(a_i-b_i)^2\) 设改变 ...
- 「AHOI / HNOI2017」影魔
「AHOI / HNOI2017」影魔 题目描述 解决这类比较复杂的区间贡献问题关键在于找到计算的对象. 比如这道题,我们计算的对象就是区间中间的最大值. 对于点\(i\),我们找到左边第一个比他大的 ...
- [LOJ 2022]「AHOI / HNOI2017」队长快跑
[LOJ 2022]「AHOI / HNOI2017」队长快跑 链接 链接 题解 不难看出,除了影响到起点和终点的射线以外,射线的角度没有意义,因为如果一定要从该射线的射出一侧过去,必然会撞到射线 因 ...
- 「GXOI / GZOI2019」宝牌一大堆 (DP)
题意 LOJ传送门 题解 可以发现「七对子」 和 「国士无双」直接暴力就行了. 唯一的就是剩下的"3*4+2". 考试的时候写了个爆搜剪枝,开了O2有50pts.写的时候发现可以D ...
- 「国家集训队」小Z的袜子
「国家集训队」小Z的袜子 传送门 莫队板子题. 注意计算答案的时候,由于分子分母都要除以2,所以可以直接约掉,这样在开桶算的时候也方便一些. 参考代码: #include <algorithm& ...
随机推荐
- 【SpringCloud】SpringCloud Alibaba Seata处理分布式事务
SpringCloud Alibaba Seata处理分布式事务 分布式事务问题 分布式前 单机库存没这个问题 O(∩_∩)O 从1:1->1:N->N:N 分布式之后 单体应用被拆分成微 ...
- spring项目使用EMQX,使用@Autowired注入失败报错空指针问题记录
目录 java客户端使用MQTT订阅消息大致流程 MQTTConnect部分代码 MQTTListener部分代码 问题分析 问题原因 解决方法 总结 参考 java客户端使用MQTT订阅消息大致流程 ...
- kafka 基础入门
kafka是什么 Kafka (Apache kafka is a distributed streaming platform) ,官方定义是一个分布式流式计算平台.在我开发的项目中,是把kafka ...
- 爬虫项目之爬取4K高清壁纸
爬虫项目之爬取4K高清壁纸 目标网址:4K壁纸高清图片_电脑桌面手机全面屏壁纸4K超清_高清壁纸4K全屏 - 壁纸汇 使用技术Selenium+Requests 下面是目标网页 思路:由于此网页是通过 ...
- jmeter之请求体类型
一.当post方法的提交数据类型(content-type)为multipart/form-data,请求体为文件文件上传. fiddler抓包请求体的name对应jmerter文件上传的参数名称,f ...
- Canvas上批量创建可视对象(DrawingVisual)管理,获取鼠标悬浮图形状态,并控制鼠标右键快捷菜单等...
近期公司有个新的定制,先简要说明下: 窗口上有个播放区域,区域上悬浮了很多可视对象(DrawingVisual),全部是动态生成的.... 现在的需求是在这些矩形框上需要添加右键快捷菜单... 需求知 ...
- kubelet 创建 Pod 前发生了什么?
Kubelet Watch 到新增的 Pod,需要做的主要有以下几件事: 管理 Pod 状态,除了更新本地缓存,还要同步给 API server 计算节点的资源是否足够创建 Pod 创建 Cgroup ...
- hadoop问题解决(七)日志/重启/开机自启动
6.1hadoop日志 Master节点 Slave节点 6.2 hadoop排错 (待补充) 6.3 spark 6.4 zookeeper 6.5 hive 6.6 kafka 7重启命令 7.1 ...
- SpringIntegrationRamble
目录 Why SpringIntegration Background Consolidate Architecture ESB service Popular Solutions Getting S ...
- 银河麒麟系统 jenkins docker 部署 自动化打包部署git 项目
Jenkins 是一个开源的自动化服务器,主要用于实现 持续集成(CI) 和 持续交付/部署(CD),其核心作用在于通过自动化流程提升软件开发和交付的效率与质量 一.环境准备 1. 安装 Docker ...