BZOJ 1835 基站选址(DP+线段树)
# include <cstdio> # include <cstring> # include <cstdlib> # include <iostream> # include <vector> # include <queue> # include <stack> # include <map> # include <set> # include <cmath> # include <algorithm> using namespace std; # define lowbit(x) ((x)&(-x)) # define pi acos(-1.0) # define eps 1e-9 # define MOD 1024523 # define INF 1000000000 # define mem(a,b) memset(a,b,sizeof(a)) # define FOR(i,a,n) for(int i=a; i<=n; ++i) # define FO(i,a,n) for(int i=a; i<n; ++i) # define bug puts("H"); # define lch p<<1,l,mid # define rch p<<1|1,mid+1,r # define mp make_pair # define pb push_back typedef pair<int,int> PII; typedef vector<int> VI; # pragma comment(linker, "/STACK:1024000000,1024000000") typedef long long LL; int Scan() { int x=0,f=1;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; } void Out(int a) { if(a<0) {putchar('-'); a=-a;} if(a>=10) Out(a/10); putchar(a%10+'0'); } const int N=20005; //Code begin... int n, k, d[N], c[N], s[N], w[N], bg[N], ed[N], seg[N<<3], tag[N<<3]; VI v[N]; LL dp[N]; void _init(){ FOR(i,1,n) { int l=d[i]-s[i], r=d[i]+s[i]; l=lower_bound(d+1,d+n+1,l)-d; r=lower_bound(d+1,d+n+1,r)-d; if (d[r]>d[i]+s[i]) --r; bg[i]=l; ed[i]=r; v[r].pb(i); } } void push_up(int p){seg[p]=min(seg[p<<1],seg[p<<1|1]);} void push_down(int p){ if (!tag[p]) return ; seg[p]+=tag[p]; tag[p<<1]+=tag[p]; tag[p<<1|1]+=tag[p]; tag[p]=0; } void init(int p, int l, int r){ if (l<r) { int mid=(l+r)>>1; tag[p]=0; init(lch); init(rch); push_up(p); } else seg[p]=dp[l], tag[p]=0; } int query(int p, int l, int r, int L, int R){ push_down(p); if (L>r||R<l) return INF; if (L<=l&&R>=r) return seg[p]; int mid=(l+r)>>1; return min(query(lch,L,R),query(rch,L,R)); } void update(int p, int l, int r, int L, int R, int val){ push_down(p); if (L>r||R<l) return ; if (L<=l&&R>=r) tag[p]=val, push_down(p); else { int mid=(l+r)>>1; update(lch,L,R,val); update(rch,L,R,val); push_up(p); } } int main () { scanf("%d%d",&n,&k); FOR(i,2,n) scanf("%d",d+i); FOR(i,1,n) scanf("%d",c+i); FOR(i,1,n) scanf("%d",s+i); FOR(i,1,n) scanf("%d",w+i); ++n; ++k; d[n]=INF; w[n]=INF; _init(); LL ans, tmp=0; FOR(i,1,n) { dp[i]=tmp+c[i]; FO(j,0,v[i].size()) tmp+=w[v[i][j]]; } ans=dp[n]; FOR(i,2,k) { init(1,1,n); FOR(j,1,n) { dp[j]=(j>1?query(1,1,n,1,j-1):0)+c[j]; FO(l,0,v[j].size()) if (bg[v[j][l]]>1) update(1,1,n,1,bg[v[j][l]]-1,w[v[j][l]]); } ans=min(ans,dp[n]); } printf("%lld\n",ans); return 0; }