[BZOJ1835] [ZJOI2010] base station site

Title Description

There \ (N \) villages located in a straight line, the \ (i (i> 1) \) villages first distance \ (1 \) distance to villages \ (D_i \) .

In these villages need to build no more than \ (K \) a communication base stations, in the first \ (i \) to establish cost base villages as \ (C_i \) .

If the distance between the first \ (I \) villages does not exceed \ (S_i \) within a communication range of the base station is established, as it is then covered.

If the first \ (i \) villages not covered, you will need to compensate them at a cost of \ (W_i \) .

The question now is, to select the location of the base station so as to minimize the total cost.

Input

Input of the first line contains two integers \ (N, K \) , the meanings indicated above.

The second line contains \ (N-1 \) integers, respectively, \ (D_2, D_3, ..., D_N of \) , which \ (N-1 \) number is incremented.

The third row contains \ (N \) integers, indicates \ (C_l, C_2, ..., C_N \) .

The fourth row contains \ (N \) integers, indicates \ (S_1, S_2, ..., S_N of \) .

The fifth line contains \ (N \) integer representing \ (W_1, W_2, ..., w_n \) .

Output

An integer representing the minimum total cost

Sample Input

3 2
1 2
2 3 2
1 1 0
10 20 30

Sample Output

4

Can easily be seen plain \ (dp \) ;

\(dp[i][j]=dp[k][j-1]+ctk[k][i]+cost[i],0<j<i\)

Wherein, \ (CTK [I] [J] \) represents the situation \ (ij of \) the sum of the compensation.

\ (O (n) \) Statistics \ (CTK [I] [J] \) , the total time complexity is \ (O (n ^ 2 * k) \)

Table method using a brush, can eliminate the use of a one-dimensional array spatially rolling.

At the same time, using the tree line maintenance interval drop off a minimum time complexity.

At this time, the total time complexity statistics are accumulated to \ (ctk [i] [j ] \) on.

How fast should the statistics \ (ctk [i] [j ] \) it?

Let's deal with that, a village about endpoints that can be covered.

The number of stores in the village on the right end of a village.

The first use of the prefix and the statistics \ (dp \) the initial array.

Consider a point \ (DP \) initial value, at which point the right endpoints can not cover the natural one point to the lower cover can not be directly accumulated compensation values can not cover the point.

Decision monotonic

Each time, only construction segment tree, using the interval to update the most value can be.

code show as below

#include <cstdio>
#include <cstring>
#include <vector>
#include <iostream>
#include <algorithm>
 
using namespace std;
 
#define LL long long
#define reg register
#define debug(x) cerr<<#x<<" = "<<x<<endl;
#define rep(a,b,c) for(reg int a=(b),a##_end_=(c); a<=a##_end_; ++a)
#define ret(a,b,c) for(reg int a=(b),a##_end_=(c); a<a##_end_; ++a)
#define drep(a,b,c) for(reg int a=(b),a##_end_=(c); a>=a##_end_; --a)
#define erep(i,e) for(reg int i=H[e]; i; i=G[i].nxt)
 
inline int Read() {
    int res=0,f=1;
    char c;
    while(c=getchar(),c<48||c>57)if(c=='-')f=0;
    do res=(res<<3)+(res<<1)+(c^48);
    while(c=getchar(),c>=48&&c<=57);
    return f?res:-res;
}
 
template<class T>inline bool Min(T &a,T const&b) {
    return a>b?a=b,1:0;
}
template<class T>inline bool Max(T &a,T const&b) {
    return a<b?a=b,1:0;
}
const int N=2e4+5,M=2e6+5;
 
int n,m,dis[N],cost[N],W[N],S[N],dp[N],L[N],R[N];
 
struct SetmentTree {
    int Mi[N<<2],lazy[N<<2];
     
    void up(int x) {
        Mi[x]=min(Mi[x<<1],Mi[x<<1|1]);
    }
    void down(int x) {
        if(!lazy[x])return;
        Mi[x<<1]+=lazy[x];
        Mi[x<<1|1]+=lazy[x];
        lazy[x<<1]+=lazy[x];
        lazy[x<<1|1]+=lazy[x];
        lazy[x]=0;
    }
    void build(int L,int R,int num) {
        lazy[num]=0;
        if(L==R) {
            Mi[num]=dp[L];
            return;
        }
        int mid=(L+R)>>1;
        build(L,mid,num<<1);
        build(mid+1,R,num<<1|1);
        up(num);
    }
    void update(int L,int R,int l,int r,int num,int x){
        if(l>r)return;
        if(l==L&&r==R){
            lazy[num]+=x;
            Mi[num]+=x;
            return;
        }
        down(num);
        int mid=(L+R)>>1;
        if(r<=mid)update(L,mid,l,r,num<<1,x);
        else if(l>mid)update(mid+1,R,l,r,num<<1|1,x);
        else {
            update(L,mid,l,mid,num<<1,x);
            update(mid+1,R,mid+1,r,num<<1|1,x);
        }
        up(num);
    }
    int query(int L,int R,int l,int r,int num){
        if(l>r)return 0;
        if(l==L&&r==R)return Mi[num];
        down(num);
        int mid=(L+R)>>1;
        if(r<=mid)return query(L,mid,l,r,num<<1);
        else if(l>mid)return query(mid+1,R,l,r,num<<1|1);
        else return min(query(L,mid,l,mid,num<<1),query(mid+1,R,mid+1,r,num<<1|1));
    }
} Tree;
 
vector<int>edge[N];
 
signed main() {
    n=Read(),m=Read();
    rep(i,2,n)dis[i]=Read();
    rep(i,1,n)cost[i]=Read();
    rep(i,1,n)S[i]=Read();
    rep(i,1,n)W[i]=Read();
    n++,dis[n]=S[n]=W[n]=1e9;//设立监视哨 
    rep(i,1,n){
        L[i]=lower_bound(dis+1,dis+n+1,dis[i]-S[i])-dis;//左端点 
        R[i]=upper_bound(dis+1,dis+n+1,dis[i]+S[i])-dis-1;//右端点 
        edge[R[i]].push_back(i);//存点 
    }
    int Sum=0;
    rep(i,1,n){
        dp[i]=Sum+cost[i];
        ret(j,0,edge[i].size())Sum+=W[edge[i][j]];//统计补偿和 
    }
    int Ans=dp[n];
    rep(i,1,m){
        Tree.build(1,n,1);
        rep(j,1,n){
            dp[j]=Tree.query(1,n,1,j-1,1)+cost[j];
            ret(k,0,edge[j].size()){
                int y=edge[j][k];
                Tree.update(1,n,1,L[y]-1,1,W[y]);
            }
        }
        Min(Ans,dp[n]);
    }
    printf("%d",Ans);
}

Guess you like

Origin www.cnblogs.com/dsjkafdsaf/p/11258484.html