P10977 Cut the Sequence 题解
大雕队列?不会不会。
线段树? YE5!YE5!
一个暴力的 \(dp\) 随便想:设 \(dp_i\) 表示考虑到序列第 \(i\) 个位置时的最小代价。
转移时:
\[dp_i=\min_{0\le j < i,\large \sum_{j+1}^{i} a_i \le m } \{dp_j+ \max_{j+1\le k \le i } \{a_k\}\}
\]
一个 \(O(n^3)\) 的爆炸 \(dp\)!尝试油画!
对 \(m\) 的限制先不看,一看感觉就是双指针能随便搞的东西。(实际上也是)
式子的后半部分贡献的长相是一个后缀 \(\max\),还需要我们动态维护,每次拓展一个位置,我们可以通过维护区间最小值再进行线段树上二分,查找出一个 \(pos\) 满足 \(a_{pos} \le a_i\) 且是最靠左的一个,那么现在再把 \([pos,i]\) 区间内的位置做决策点时,后半部分的贡献都是 \(a_i\),所以在线段树上进行区间覆盖修改为 \(a_i\)。
发现我们还有一个决策点上的 \(dp\) 值没有维护上,如果直接附加在了线段树上,那区间覆盖的时候该怎么维护?实际上 \(dp\) 值是非严格递增的,而我们线段树上维护的是最小值,所以对于一个区间在 \([l,r]\) 的节点进行区间覆盖为 \(v\) 后,我们可以直接把答案值修改为 \(dp_{l-1}+v\)。
最后来看 \(m\) 的限制,哦,确实是双指针。
总时间复杂度 \(O(n \log n)\)
点击查看代码
const int N=1e5+5;
const int inf=1e18;
int n,m,a[N],sum[N],dp[N];
int mn[N*3],t[N*3],tag[N*3],P=1,DEP;
void pushup(int i){
mn[i]=min(mn[ls(i)],mn[rs(i)]);
t[i]=min(t[ls(i)],t[rs(i)]);
}
void push(int i,int v,int dep){
mn[i]=v,tag[i]=v;
int l=(i<<dep)-P;
if(l-1>=0) t[i]=dp[l-1]+v;
}
void pushdown(int i,int dep){
if(tag[i]!=-1){
push(ls(i),tag[i],dep-1);
push(rs(i),tag[i],dep-1);
tag[i]=-1;
}
}
int search(int v){
int dep=0,i=1;
while(dep<DEP){
pushdown(i,DEP-dep);
if(mn[ls(i)]<=v) i=i<<1;
else i=i<<1|1;
dep++;
}
return i-P;
}
void update(int l,int r,int v){
l+=P-1,r+=P+1;
int dep=0;
for(int i=DEP;i;i--) pushdown(l>>i,i),pushdown(r>>i,i);
while(l^1^r){
if(~l&1) push(l^1,v,dep);
if(r&1) push(r^1,v,dep);
l>>=1,r>>=1,dep++;
pushup(l),pushup(r);
}
for(l>>=1;l;l>>=1) pushup(l);
}
int query(int l,int r){
l+=P-1,r+=P+1;
int res=inf;
for(int i=DEP;i;i--) pushdown(l>>i,i),pushdown(r>>i,i);
while(l^1^r){
if(~l&1) res=min(res,t[l^1]);
if(r&1) res=min(res,t[r^1]);
l>>=1,r>>=1;
}
return res;
}
void xpigeon(){
rd(n,m);
for(int i=1;i<=n;i++){
rd(a[i]);
sum[i]=sum[i-1]+a[i];
}
while(P<=n+1) P<<=1,DEP++;
memset(tag,-1,sizeof(tag));
for(int i=1,l=1;i<=n;i++){
while(l<=i && sum[i]-sum[l-1]>m) l++;
if(l>i) {cout<<-1;return ;}
int pos=search(a[i]);
update(pos,i,a[i]);
dp[i]=query(l,i);
}
cout<<dp[n]<<'\n';
}
signed main() {
xpigeon();
return 0;
}
可能后续会补一个单调队列的做法。

浙公网安备 33010602011771号