CF1884C Medium Design
思路
Step1. 贪心
拿到题后,第一时间想到贪心,如果这个区间加上会使答案变小或不变就不加。
但是很显然,这个贪心是错误的。
如果答案的最大值在区间 B,但是先加了区间 A,导致加区间 B 使答案不变,那么这样就会使答案变劣。
所以贪心是错误的。
Step2. 枚举
接着,想到了可以枚举最小值,如果某个区间包含了这个最小值,那么这个区间加上后的答案一定是不优于不加上这个区间的答案,所以所有包含了这个最小值的区间都不需要加,那么再把所有最小值的答案取个最大值即可。
当然了,区间的值大,所以需要离散化。
有个巨佬朋友写过这种做法的题解。
这里就不赘述了。
Step3. 优化
事实上,最小值的选择的讨论是多余的,假设最小值选在 x 点,那么所有横跨 x 的区间都是无效的,那么可以对答案做出贡献的只有两个端点都在 x 左侧或者都在右侧的区间才有用,那么假设最后的最大值在 x 左侧,那么在 x 右侧的区间无用,这样的话,把 x 右移可以让区间变多或不变,那么答案将会变优或者不变,同理最大值在 x 右侧也可以得到 x 在左端点不劣。
总而言之就是,如果 x 选在中间,那么答案一定不优于 x 选择两端的情况。
所以我们只需要讨论两种情况即可。
所以如果一个区间左端点有 1 的话,就把这个区间加给第一组线段树。
如果一个区间右端点有 m 的话,就把这个区间加给第二组线段树。
注意:一个区间可以加给两个线段树。
那么最后的答案就是两组线段树维护的最大值的较大值。
同样地,需要离散化。
AC code
#include<bits/stdc++.h> using namespace std; struct segtree { struct node{int l,r,maxn,tag;}t[800005]; inline void pushup(int p){t[p].maxn=max(t[p<<1].maxn,t[p<<1|1].maxn);} inline void addtag(int p,int k){t[p].maxn+=k,t[p].tag+=k;} inline void pushdown(int p){addtag(p<<1,t[p].tag),addtag(p<<1|1,t[p].tag),t[p].tag=0;} void build(int p,int l,int r) { t[p].l=l,t[p].r=r,t[p].maxn=t[p].tag=0; if(l==r) return; int mid=l+r>>1; build(p<<1,l,mid),build(p<<1|1,mid+1,r); } void update(int p,int l,int r) { if(t[p].l>=l&&t[p].r<=r){addtag(p,1);return;} if(t[p].tag) pushdown(p); int mid=t[p].l+t[p].r>>1; if(mid>=l) update(p<<1,l,r); if(mid<r) update(p<<1|1,l,r); pushup(p); } }t1,t2; int T,n,m,l[200005],r[200005],a[400005],num; int main() { scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) scanf("%d%d",&l[i],&r[i]),a[i*2-1]=l[i],a[i*2]=r[i];a[n*2+1]=1,a[n*2+2]=m; sort(a+1,a+2*n+3),num=unique(a+1,a+2*n+3)-a-1; t1.build(1,1,num),t2.build(1,1,num); //cout<<num<<endl; for(int i=1;i<=n;++i) { l[i]=lower_bound(a+1,a+num+1,l[i])-a,r[i]=lower_bound(a+1,a+num+1,r[i])-a; if(l[i]!=1) t1.update(1,l[i],r[i]); if(r[i]!=num) t2.update(1,l[i],r[i]); } printf("%d\n",max(t1.t[1].maxn,t2.t[1].maxn)); } return 0; }
Step4. 进一步优化
可以发现,只需要区间修改和一次区间查询,所以实际上可以直接使用差分数组进行维护,如果不算上离散化要用到的排序的话,时间复杂度更优,代码也更简单。
主要是因为前面的方法需要线段树,所以最开始没想到差分,辛辛苦苦写完了才发现更本不需要。
因为代码难度低,所以这里就不放差分版的代码了 (绝对不是我懒得再写一个差分了)。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具