标签:line 一个 bit tree printf ++i 线段树 邻接表 shu
#pragma GCC optimize("O3")
#include <bits/stdc++.h>
#define N 20005
#define inf 0x3f3f3f3f
using namespace std;
inline int read()
{
register int x=0,f=1;register char ch=getchar();
while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
return x*f;
}
inline int Min(register int a,register int b)
{
return a<b?a:b;
}
int D[N],C[N],S[N],W[N],lr[N],rr[N],f[N];
vector<int> vq[N];
int ql,qr;
struct Segment_tree{
int minn[N<<2],tag[N<<2];
inline void pushup(register int x)
{
minn[x]=Min(minn[x<<1],minn[x<<1|1]);
}
inline void build(register int x,register int l,register int r)
{
tag[x]=0;
if(l==r)
{
minn[x]=f[l];
return;
}
int mid=(l+r)>>1;
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
pushup(x);
}
inline void maintain(register int x,register int l,register int r)
{
if(l!=r)
pushup(x);
minn[x]+=tag[x];
}
inline void update(register int x,register int l,register int r,register int v)
{
if(ql<=l&&qr>=r)
tag[x]+=v;
else
{
int mid=(l+r)>>1;
if(ql<=mid)
update(x<<1,l,mid,v);
if(qr>mid)
update(x<<1|1,mid+1,r,v);
}
maintain(x,l,r);
}
inline int query(register int x,register int l,register int r,register int v)
{
if(ql<=l&&qr>=r)
return minn[x]+v;
int ret=inf,mid=(l+r)>>1;
if(ql<=mid)
ret=Min(ret,query(x<<1,l,mid,v+tag[x]));
if(qr>mid)
ret=Min(ret,query(x<<1|1,mid+1,r,v+tag[x]));
return ret;
}
}T;
int main()
{
int n=read(),k=read();
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();
++n,++k;
D[n]=inf;
for(register int i=1;i<=n;++i)
{
lr[i]=lower_bound(D+1,D+n+1,D[i]-S[i])-D;
rr[i]=lower_bound(D+1,D+n+1,D[i]+S[i])-D;
if(D[i]+S[i]<D[rr[i]])
--rr[i];
vq[rr[i]].push_back(i);
}
int ans=inf;
for(register int j=1;j<=k;++j)
{
if(j==1)
{
int tot=0;
for(register int i=1;i<=n;++i)
{
f[i]=tot+C[i];
for(register int tmp=0;tmp<vq[i].size();++tmp)
tot+=W[vq[i][tmp]];
}
ans=Min(ans,f[n]);
continue;
}
T.build(1,1,n);
for(register int i=1;i<=n;++i)
{
ql=1,qr=i-1;
int add=qr?T.query(1,1,n,0):0;
f[i]=add+C[i];
for(register int tmp=0;tmp<vq[i].size();++tmp)
{
ql=1,qr=lr[vq[i][tmp]]-1;
if(qr>0)
T.update(1,1,n,W[vq[i][tmp]]);
}
}
ans=Min(ans,f[n]);
}
printf("%d",ans);
return 0;
}
【题解】Luogu P2605 [ZJOI2010]基站选址
标签:line 一个 bit tree printf ++i 线段树 邻接表 shu
原文地址:https://www.cnblogs.com/yzhang-rp-inf/p/9742546.html