我看着题解写的(不太懂,知道原理,不会写),觉得题解的代码实现不是很丝滑,改了一些地方(例如ans直接统计、初始情况为0的情况),但是发现过不了。
#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
const int maxn=2e4+10,maxh=(1<<30)-1;
int N,M,pos[maxn],v1[maxn],len[maxn],v2[maxn],dp[maxn],pl[maxn],pr[maxn],ans=maxh;
vector<int>vec[maxn];
vector<int>::iterator it;
struct node{int l,r,v,lazy;}f[maxn<<3];
void pushup(int t){f[t].v=min(f[t<<1].v,f[t<<1|1].v);}
void pushdown(int t){
int l=f[t].l,r=f[t].r;
f[l].v+=f[t].lazy,f[r].v+=f[t].lazy;
f[l].lazy+=f[t].lazy,f[r].lazy+=f[t].lazy;
f[t].lazy=0;
}
void build(int t,int l,int r){
f[t].l=l,f[t].r=r,f[t].lazy=0;
if(l==r){f[t].v=dp[l];return;}
int m=(l+r)>>1;
build(t<<1,l,m),build(t<<1|1,m+1,r);
pushup(t);
}
void change(int t,int ul,int ur,int x){
int l=f[t].l,r=f[t].r;
if(ul<=l&&r<=ur){f[t].v+=x;return;}
pushdown(t);int m=(l+r)>>1;
if(ul<=m) change(t<<1,ul,ur,x);
if(m<ur) change(t<<1|1,ul,ur,x);
pushup(t);
}
int ask(int t,int ul,int ur){
int l=f[t].l,r=f[t].r;
if(ul<=l&&r<=ur) return f[t].v;
pushdown(t);int m=(l+r)>>1,rt=maxh;
if(ul<=m) rt=min(rt,ask(t<<1,ul,ur));
if(m<ur) rt=min(rt,ask(t<<1|1,ul,ur));
return rt;
}
int qd(){
int rt=0;char c=getchar();
while(c<'0'||c>'9') c=getchar();
while('0'<=c&&c<='9') rt=(rt<<3)+(rt<<1)+c-48,c=getchar();
return rt;
}
int main(){
N=qd(),M=qd();
for(int i=2;i<=N;i++) pos[i]=qd();
for(int i=1;i<=N;i++) v1[i]=qd();
for(int i=1;i<=N;i++) len[i]=qd();
for(int i=1;i<=N;i++) v2[i]=qd(),dp[i]=dp[i-1]+v2[i];
for(int i=1;i<=N;i++){//a point ex to right and left most
pl[i]=lower_bound(pos+1,pos+N+1,pos[i]-len[i])-pos;
pr[i]=lower_bound(pos+1,pos+N+1,pos[i]+len[i])-pos;
if(pos[pr[i]]>pos[i]+len[i]) pr[i]--;
vec[pr[i]].push_back(i);
}
// for(int i=1;i<=N;i++){
// printf("%d:at %d len %d l %d r %d\n",i,pos[i],len[i],pl[i],pr[i]);
// }
// int sum=0;
// for(int i=1;i<=N;i++){
// dp[i]=sum+v1[i];
// for(it=vec[i].begin();it!=vec[i].end();it++) sum+=v2[*it];
// }
ans=dp[N];
for(int i=1;i<=M;i++){
build(1,1,N);
for(int j=1;j<=N;j++){
dp[j]=ask(1,1,j-1)+v1[j];
// printf("dp %d=%d\n",j,dp[j]);
for(it=vec[j].begin();it!=vec[j].end();it++){
int k=*it;
change(1,1,pl[k]-1,v2[k]);
// printf("change %d %d\n",pl[k]-1,v2[k]);
}
}
// printf("f[1].v=%d\n",f[1].v);
ans=min(ans,f[1].v);
}
printf("%d\n",ans);
return 0;
}