【ARC085F】NRE
题目描述
一个全部为
算法解析
很多区间,求最值,不可贪心,一眼 dp。
考虑一个状态数为
如果不交:
如果相交:
分为这两种情况,由于
但是笔者在这样实现的时候就傻眼了:第
事实上,我们尝试转变线段树的模式,每个
这启发我们线段树的模式不同,最后求答案的难易度也不同,写线段树时要向模板题那样明确你要什么操作。
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5,inf = 0x3f3f3f3f;
struct Segment_Tree{
int a[N << 2],tag[N << 2];
inline void pushdown(int pos)
{
a[pos << 1] = min(a[pos << 1],tag[pos]);
a[pos << 1 | 1] = min(a[pos << 1 | 1],tag[pos]);
tag[pos << 1] = min(tag[pos << 1],tag[pos]);
tag[pos << 1 | 1] = min(tag[pos << 1 | 1],tag[pos]);
tag[pos] = inf;
}
inline void pushup(int pos) {a[pos] = min(a[pos << 1],a[pos << 1 | 1]);}
inline void modify(int l,int r,int L,int R,int k,int pos)
{
if(L <= l && r <= R) {a[pos] = min(a[pos],k); tag[pos] = min(tag[pos],k); return;}
int mid = (l + r) >> 1;
pushdown(pos);
if(L <= mid) modify(l,mid,L,R,k,pos << 1);
if(R > mid) modify(mid + 1,r,L,R,k,pos << 1 | 1);
pushup(pos);
}
inline int query(int l,int r,int x,int pos)
{
if(l == r) return a[pos];
int mid = (l + r) >> 1,ret = inf;
pushdown(pos);
if(x <= mid) ret = query(l,mid,x,pos << 1);
else ret = query(mid + 1,r,x,pos << 1 | 1);
pushup(pos);
return ret;
}
}t1,t2;
int f[N],n,b[N],m,num0[N],num1[N];
struct Q{
int l,r;
}q[N];
int main()
{
memset(t1.a,0x3f,sizeof(t1.a)); memset(t2.a,0x3f,sizeof(t2.a)); memset(t1.tag,0x3f,sizeof(t1.tag)); memset(t2.tag,0x3f,sizeof(t2.tag));
scanf("%d",&n);
for(int i = 1;i <= n;i++) scanf("%d",&b[i]);
for(int i = 1;i <= n;i++) num0[i] = num0[i - 1] + (b[i] == 0),num1[i] = num1[i - 1] + (b[i] == 1);
scanf("%d",&m);
for(int i = 1;i <= m;i++) scanf("%d%d",&q[i].l,&q[i].r);
sort(q + 1,q + m + 1,[&](Q x,Q y) {if(x.r != y.r) return x.r < y.r; return x.l > y.l;});
t1.modify(0,n,0,n,0,1); q[0].r = 0;
for(int i = 1;i <= m;i++)
{
int val1 = t1.query(0,n,q[i].l,1) + num1[q[i].l - 1] + num0[q[i].r] - num0[q[i].l - 1];
int val2 = t2.query(0,n,q[i].l,1) + num0[q[i].r];
f[i] = min(val1,val2);
t1.modify(0,n,q[i].r + 1,n,f[i] - num1[q[i].r],1);
t2.modify(0,n,q[i].l,q[i].r,f[i] - num0[q[i].r],1);
}
int ans = inf;
for(int i = 0;i <= m;i++) ans = min(ans,f[i] + num1[n] - num1[q[i].r]);
printf("%d",ans);
return 0;
}
分类:
题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话