题解:P12845 [蓝桥杯 2025 国 A] 连锁反应
lzx20120124 · · 题解
题目
这不一眼 DP 吗?
首先求出每个炸弹引爆后的范围,细节的可以看这篇这不应该比建图什么的好想吗。
设
然后更新
while(ql[i]>1&&a[i].p-a[ql[i]-1].p<=a[i].l)
a[i].r=max(a[i].r,a[ql[i]-1].r-(a[i].p-a[ql[i]-1].p)),ql[i]=ql[ql[i]-1];
更新
while(qr[i]<n&&a[qr[i]+1].p-a[i].p<=a[i].r)
ql[i]=min(ql[i],ql[qr[i]+1]),qr[i]=qr[qr[i]+1];
而这是类似路径压缩的,时间复杂度可以看成
接下来就很简单了。
设
如果
如果
但这是
最后时间复杂度
:::success[code]
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,l,r) for(int i=(l);i<=(r);++i)
#define per(i,r,l) for(int i=(r);i>=(l);--i)
const int N=2e5+5,M=1e6+5;
const ll inf=1e9;
int n;
struct node{int p,l,r;}a[N];
struct BIT_mn{
ll t[M];
BIT_mn(){memset(t,0x3f,sizeof t);}
void up(ll x,ll z){if(x<=0)return;for(;x<M;x+=x&-x)t[x]=min(t[x],z);}
ll get(ll x){ ll res=1e18;for(;x;x-=x&-x)res=min(res,t[x]);return res;}
}A;
ll ql[N],qr[N];
ll dp[N];
void solve(){
cin>>n;
rep(i,1,n) cin>>a[i].p>>a[i].l>>a[i].r,ql[i]=qr[i]=i;
sort(a+1,a+1+n,[](node qq,node ww){return qq.p<ww.p;});
rep(i,2,n) while(ql[i]>1&&a[i].p-a[ql[i]-1].p<=a[i].l) a[i].r=max(a[i].r,a[ql[i]-1].r-(a[i].p-a[ql[i]-1].p)),ql[i]=ql[ql[i]-1];
per(i,n-1,1) while(qr[i]<n&&a[qr[i]+1].p-a[i].p<=a[i].r) ql[i]=min(ql[i],ql[qr[i]+1]),qr[i]=qr[qr[i]+1];
memset(dp,0x3f,sizeof dp);
dp[0]=0;
A.up(n-0+1,0);
rep(i,1,n){
ll v=A.get(n-(ql[i]-1)+1)+1;
dp[i]=min(v,dp[i]);
dp[qr[i]]=min(v,dp[qr[i]]);
A.up(n-i+1,dp[i]);
}
cout<<dp[n]<<'\n';
}
int main(){
cin.tie(0)->ios::sync_with_stdio(false);
solve();
}
:::