[ZJOI2010]基站选址
线段树优化
首先根据题意列出
然后滚动掉
上面
这个
考虑区间会很大,我们先对村庄离散化
存储village
每次
每次转移查询
维护区间之间连锁的影响,我们用邻接表来维护
#include<bits/stdc++.h>
#define int long long
#define ls (o<<1)
#define rs (o<<1|1)
using namespace std;
const int N=20010;
const int inf=2e9;
int read() {
int x=0,f=1;
char ch=getchar();
while(ch<48||ch>57) {
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>=48&&ch<=57) {
x=(x<<3)+(x<<1)+(ch^48);
ch=getchar();
}
return x*f;
}
int head[N],to[N*2],tot=0,nxt[N*2];
void add(int u,int v) {
nxt[++tot]=head[u];
to[tot]=v;
head[u]=tot;
}
int d[N],s[N],w[N],c[N];
int sum[N*4],tag[N*4],f[N];
void push_up(int o) {
sum[o]=min(sum[ls],sum[rs]);
}
void build(int o,int l,int r) {
tag[o]=0;
if(l==r) {
sum[o]=f[l];
return ;
}
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
push_up(o);
}
void push_down(int o,int l,int r) {
sum[ls]+=tag[o];
sum[rs]+=tag[o];
tag[ls]+=tag[o];
tag[rs]+=tag[o];
tag[o]=0;
}
void update(int o,int l,int r,int x,int y,int t) {
if(x<=l&&r<=y) {
tag[o]+=t;
sum[o]+=t;
return ;
}
int mid=(l+r)>>1;
if(tag[o]) push_down(o,l,r);
if(x<=mid) update(ls,l,mid,x,y,t);
if(y>mid) update(rs,mid+1,r,x,y,t);
push_up(o);
}
int query(int o,int l,int r,int x,int y) {
int ans=inf;
if(x<=l&&r<=y) {
return sum[o];
}
int mid=(l+r)>>1;
if(tag[o]) push_down(o,l,r);
if(x<=mid) ans=min(ans,query(ls,l,mid,x,y));
if(y>mid) ans=min(ans,query(rs,mid+1,r,x,y));
return ans;
}
int n,k,ANS,st[N],ed[N],num=0;
signed main() {
n=read();
k=read();
for(int i=2;i<=n;i++) d[i]=read();
for(int i=1;i<=n;i++) c[i]=read();
for(int i=1;i<=n;i++) s[i]=read();
for(int i=1;i<=n;i++) w[i]=read();
n++;
k++;
d[n]=w[n]=inf;
s[n]=c[n]=0;
for(int i=1;i<=n;i++) {
st[i]=lower_bound(d+1,d+n+1,d[i]-s[i])-d;
ed[i]=lower_bound(d+1,d+n+1,d[i]+s[i])-d;
if(d[ed[i]]>d[i]+s[i]) ed[i]--;
add(ed[i],i);
}
//k=1
for(int i=1;i<=n;i++) {
f[i]=num+c[i];
for(int j=head[i];j;j=nxt[j]) {
int v=to[j];
num+=w[v];
}
}
ANS=f[n];
for(int j=2;j<=k;j++) {
build(1,1,n);
for(int i=1;i<=n;i++) {
if(i>=2) {
f[i]=query(1,1,n,1,i-1)+c[i];
} else {
f[i]=inf;
}
for(int u=head[i];u;u=nxt[u]) {
int v=to[u];
if(st[v]>1) update(1,1,n,1,st[v]-1,w[v]);
}
}
ANS=min(ANS,f[n]);
}
printf("%lld\n",ANS);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!