比赛 |
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);
}