rt,不知道是常数太大还是怎么回事一直TLE。
#include <bits/stdc++.h>
using namespace std;
const int N = 2e4 + 5;
inline int read() {
int x=0,f=1;
char ch=getchar();
while (ch<'0' || ch>'9') {
if (ch=='-')f=-1;
ch=getchar();
}
while ('0'<=ch && ch<='9') {
x=(x<<3)+(x<<1)+(ch^48);
ch=getchar();
}
return x*f;
}
inline void write(int x) {
static int sta[35];
int top = 0;
do {
sta[top++] = x % 10,x /= 10;
} while (x);
while (top) putchar(sta[--top] + 48);
}
namespace Chain_forward_star{
int tot = 0;
struct node{
int to;
int nxt;
}edge[N << 1];
int head[N];
void add(int u,int v){
edge[++tot].to = v;
edge[tot].nxt = head[u];
head[u] = tot;
}
}
using namespace Chain_forward_star;
int n,k,nums[N],d[N],c[N],s[N],w[N],st[N],ed[N];
int my_left[N << 2],my_right[N << 2];
int sum[N << 2],lazy[N << 2];
inline void push_up(int u){
sum[u] = min(sum[u << 1],sum[u << 1 | 1]);
}
inline void update(int x,int p){
sum[x] += p;
lazy[x] += p;
}
inline void push_down(int x){
if (lazy[x]){
update(x << 1,lazy[x]);
update(x << 1 | 1,lazy[x]);
lazy[x] = 0;
}
}
inline void init(int l,int r,int u){
my_left[u] = l;
my_right[u] = r;
if (my_left[u] == my_right[u]){
return;
}
int mid = (l + r) >> 1;
init(l,mid,u << 1);
init(mid + 1,r,u << 1 | 1);
push_up(u);
}
inline void build(int l,int r,int u){
lazy[u] = 0;
if (my_left[u] == my_right[u]){
sum[u] = nums[l];
return;
}
int mid = (l + r) >> 1;
build(l,mid,u << 1);
build(mid + 1,r,u << 1 | 1);
push_up(u);
}
inline int query(int u,int l,int r){
if (my_left[u] == my_right[u]) return sum[u];
push_down(u);
int mid = (my_left[u] + my_right[u]) >> 1;
if (r <= mid) return query(u << 1,l,r);
else if (l > mid) return query(u << 1 | 1,l,r);
else return min(query(u << 1,l,mid),query(u << 1 | 1,mid + 1,r));
}
inline void modify(int u,int l,int r,int p){
if (my_left[u] == my_right[u]){
update(u,p);
return;
}
push_down(u);
int mid = (my_left[u] + my_right[u]) >> 1;
if (r <= mid) modify(u << 1,l,r,p);
else if (l > mid) modify(u << 1 | 1,l,r,p);
else{
modify(u << 1,l,mid,p);
modify(u << 1 | 1,mid + 1,r,p);
}
push_up(u);
}
int main(){
n = read(),k = read();k++;
for (register int i = 2;i <= n;i++) d[i] = read();
for (register int i = 1;i <= n;i++) c[i] = read();
for (register int i = 1;i <= n;i++) s[i] = read();
for (register int i = 1;i <= n;i++) w[i] = read();
d[++n] = 1e9 + 7,w[n] = 1e9 + 7;
for (register int i = 1;i <= n;i++){
st[i] = lower_bound(d + 1,d + 1 + n,d[i] - s[i]) - d;
ed[i] = lower_bound(d + 1,d + 1 + n,d[i] + s[i]) - d;
if (d[ed[i]] > d[i] + s[i]) ed[i]--;
add(ed[i],i);
}
int res = 0,ans = 0;
for (register int i = 1;i <= n;i++){
nums[i] = res + c[i];
for (int xx = head[i];xx;xx = edge[xx].nxt) res += w[edge[xx].to];
}
ans = nums[n];
init(1,n,1);
for (register int i = 2;i <= k;i++){
build(1,n,1);
for (register int j = 1;j <= n;j++){
nums[j] = (j > (i - 1) ? query(1,i - 1,j - 1) : 0) + c[j];
for (register int xx = head[j];xx;xx = edge[xx].nxt){
if (st[edge[xx].to] > 1) modify(1,1,st[edge[xx].to] - 1,w[edge[xx].to]);
}
}
ans = min(ans,nums[n]);
}
write(ans);
}