比赛 2022级DP专题练习赛4 评测结果 AAAAAAAAAA
题目名称 基站选址 最终得分 100
用户昵称 op_组撒头屯 运行时间 1.875 s
代码语言 C++ 内存使用 6.79 MiB
提交时间 2023-02-20 20:21:45
显示代码纯文本
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define ld long double
#define pii pair<int,int>
#define vi vector<int>
#define si set<int>
#define unsi unordered_set<int>
#define qi queue<int>
#define sti stack<int>
#define pqi priority_queue<int>
#define mii map<int,int>
#define unmii unordered_map<int,int>
#define fi first
#define se second
#define pb push_back
#define clr(f,n) memset(f,0,sizeof(int)*(n))
#define cpy(f,g,n) memcpy(f,g,sizeof(int)*(n))
const int N=20000+5;
const ll inf=0x3f3f3f3f3f3f;
int n,m;
ll d[N],c[N],s[N],f[N];
struct sdf{
    int l,r;ll w;
}p[N];
bool cmp(sdf x,sdf y){
    if (x.r!=y.r)return x.r<y.r;
    return x.l<y.l;
}
struct segtree{
    int l,r;ll val,tag;
}tr[N<<2];
void pushup(int pt){
    tr[pt].val=min(tr[pt*2].val,tr[pt*2+1].val);
}
void build(int pt,int l,int r){
    tr[pt]={l,r,inf,0};
    if (l==r){
        tr[pt].val=f[l];return ;
    }
    int mid=(l+r)/2;
    build(pt*2,l,mid);build(pt*2+1,mid+1,r);
    pushup(pt);
    return ;
}
void spread(int pt){
    if (tr[pt].tag){
        tr[pt*2].tag+=tr[pt].tag;
        tr[pt*2+1].tag+=tr[pt].tag;
        tr[pt*2].val+=tr[pt].tag;
        tr[pt*2+1].val+=tr[pt].tag;
        tr[pt].tag=0;
    }
}
void add(int pt,int x,int y,ll w){
    if (y<=0)return ;
    int l=tr[pt].l,r=tr[pt].r;
    if (x<=l&&r<=y){
        tr[pt].val+=w;
        tr[pt].tag+=w;return ;
    }
    spread(pt);
    int mid=(l+r)/2;
    if (x<=mid)add(pt*2,x,y,w);
    if (mid+1<=y)add(pt*2+1,x,y,w);
    pushup(pt);return ;
}
ll query(int pt,int x,int y){
    if (y<=0)return inf;
    int l=tr[pt].l,r=tr[pt].r;
    if (x<=l&&r<=y){
        return tr[pt].val;
    }
    spread(pt);
    int mid=(l+r)/2;ll ans=inf;
    if (x<=mid)ans=min(ans,query(pt*2,x,y));
    if (mid+1<=y)ans=min(ans,query(pt*2+1,x,y));
    pushup(pt);return ans;
}
int main(){
	freopen ("base.in","r",stdin);
	freopen ("base.out","w",stdout);
	scanf("%d%d",&n,&m);
	for (int i=2;i<=n;i++)scanf("%lld",&d[i]);
	for (int i=1;i<=n;i++)scanf("%lld",&c[i]);
	for (int i=1;i<=n;i++)scanf("%lld",&s[i]);
	for (int i=1;i<=n;i++)scanf("%lld",&p[i].w);
	for (int i=1;i<=n;i++){
	    p[i].l=lower_bound(d+1,d+n+1,d[i]-s[i])-d;
	    p[i].r=upper_bound(d+1,d+n+1,d[i]+s[i])-d-1;
    }
    sort(p+1,p+n+1,cmp);
    n++;m++;p[n]={n,n,inf};d[n]=inf;c[n]=0;
    
    ll now=0;
    for (int i=1,j=1;i<=n;i++){
        f[i]=now+c[i];
        while(j<=n&&p[j].r==i){
            now+=p[j].w;j++;
        }
    }
    ll ans=f[n];
    for (int k=2;k<=m;k++){
        build(1,1,n);
        for (int i=1,j=1;i<=n;i++){
            f[i]=query(1,1,i-1)+c[i];
            while(j<=n&&p[j].r==i){
                add(1,1,p[j].l-1,p[j].w);j++;
            }
        }
        ans=min(ans,f[n]);
    }
    printf("%lld\n",ans);
}