zoukankan      html  css  js  c++  java
  • luogu2605 基站选址 (线段树优化dp)

    设f[i][j]表示在第i个村庄建第j个基站的花费

    那么有$f[i][j]=min{f[k][j-1]+w[k,i]}$,其中w[k,i]表示在k,i建基站,k,i中间的不能被满足的村庄的赔偿金之和

    如果把每个村庄能被满足的区间处理出来,记做$[l_i,r_i]$,那么i,j不能满足的村庄,就是$i<l,r<j$的村庄

    考虑将$f[i][k]+w[i,j]$的i固定,而j随着dp进行而变化,这样维护K个线段树

    那么当j越来越大,会有更多的村庄[l,r]变得满足r<j,被加入到线段树的区间[1,l-1]中

    用堆来维护这些村庄,按r从大到小排序即可

    复杂度$O(nklogn)$

      1 #include<bits/stdc++.h>
      2 #define pa pair<ll,ll>
      3 #define CLR(a,x) memset(a,x,sizeof(a))
      4 #define MP make_pair
      5 using namespace std;
      6 typedef long long ll;
      7 const int maxn=2e4+10,maxk=105;
      8 
      9 inline char gc(){
     10     return getchar();
     11     static const int maxs=1<<16;static char buf[maxs],*p1=buf,*p2=buf;
     12     return p1==p2&&(p2=(p1=buf)+fread(buf,1,maxs,stdin),p1==p2)?EOF:*p1++;
     13 }
     14 inline ll rd(){
     15     ll x=0;char c=gc();bool neg=0;
     16     while(c<'0'||c>'9'){if(c=='-') neg=1;c=gc();}
     17     while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+c-'0',c=gc();
     18     return neg?(~x+1):x;
     19 }
     20 
     21 int N,K,f[maxn][maxk],pos[maxn],cost[maxn];
     22 struct Node{
     23     int l,r,w;
     24 }p[maxn];
     25 int mi[maxk*maxn*2],laz[maxk*maxn*2],ch[maxk*maxn*2][2],rt[maxk],pct;
     26 inline bool operator < (Node a,Node b){return a.r>b.r;}
     27 priority_queue<Node> q;
     28 
     29 inline void tag(int p,int v){
     30     mi[p]+=v,laz[p]+=v;
     31 }
     32 
     33 inline void pushdown(int p){
     34     if(!laz[p]) return;
     35     int a=ch[p][0],b=ch[p][1];
     36     if(a) tag(a,laz[p]);
     37     if(b) tag(b,laz[p]);
     38     laz[p]=0;
     39 }
     40 inline void update(int p){
     41     mi[p]=min(mi[ch[p][0]],mi[ch[p][1]]);
     42 }
     43 
     44 inline void add(int p,int l,int r,int x,int y,int z){
     45     if(x<=l&&r<=y) tag(p,z);
     46     else{
     47         pushdown(p);int m=l+r>>1;
     48         if(x<=m) add(ch[p][0],l,m,x,y,z);
     49         if(y>=m+1) add(ch[p][1],m+1,r,x,y,z);
     50         update(p);
     51     }
     52 }
     53 
     54 inline int query(int p,int l,int r,int x,int y){
     55     if(x<=l&&r<=y) return mi[p];
     56     int m=l+r>>1;pushdown(p);int re=1e9;
     57     if(x<=m) re=query(ch[p][0],l,m,x,y);
     58     if(y>=m+1) re=min(re,query(ch[p][1],m+1,r,x,y));
     59     return re;
     60 }
     61 
     62 inline void change(int p,int l,int r,int x,int y){
     63     if(l==r) mi[p]=y;
     64     else{
     65         int m=l+r>>1;pushdown(p);
     66         if(x<=m) change(ch[p][0],l,m,x,y);
     67         else change(ch[p][1],m+1,r,x,y);
     68         update(p);
     69     }
     70 }
     71 
     72 inline void build(int &p,int l,int r){
     73     p=++pct;mi[p]=1e9+233;
     74     if(l<r){
     75         int m=l+r>>1;
     76         build(ch[p][0],l,m);build(ch[p][1],m+1,r);
     77     }
     78 }
     79 
     80 int main(){
     81     //freopen("","r",stdin);
     82     int i,j,k;
     83     N=rd(),K=rd();
     84     for(i=2;i<=N;i++)
     85         pos[i]=rd();
     86     for(i=1;i<=N;i++)
     87         cost[i]=rd();
     88     pos[N+1]=1e9+1;
     89     for(i=1;i<=N;i++){
     90         int s=rd();
     91         p[i].l=lower_bound(pos+1,pos+N+1,pos[i]-s)-pos;
     92         p[i].r=upper_bound(pos+1,pos+N+1,pos[i]+s)-pos-1;
     93     }
     94     for(i=1;i<=N;i++)
     95         p[i].w=rd();
     96     p[N+1].l=N+1,p[N+1].r=N+1,p[N+1].w=233333333,N++,K++;
     97     CLR(f,127);f[0][0]=0;
     98     for(i=1;i<=K;i++) build(rt[i],1,N);
     99     for(i=1;i<=N;i++){
    100         while(!q.empty()){
    101             Node p=q.top();
    102             if(p.r>=i) break;
    103             q.pop();f[0][0]+=p.w;
    104             for(k=1;k<=min(p.l-1,K);k++)
    105                 add(rt[k],1,N,1,p.l-1,p.w);
    106         }
    107         f[i][1]=f[0][0]+cost[i];change(rt[1],1,N,i,f[i][1]);
    108         for(k=2;k<=min(i,K);k++){
    109             f[i][k]=query(rt[k-1],1,N,1,i-1)+cost[i];
    110             change(rt[k],1,N,i,f[i][k]);
    111         }
    112         q.push(p[i]);
    113     }
    114     int ans=2e9;
    115     for(i=1;i<=K;i++) ans=min(ans,f[N][i]);
    116     printf("%d
    ",ans);
    117     return 0;
    118 }
  • 相关阅读:
    设计模式之工厂模式
    东方通 部署项目 报错 内存溢出解决
    java8提取对象集合中的一项属性
    vue 函数节流
    ALINK(三十一):特征工程(十)特征选择(二)卡方选择器 (ChiSqSelectorBatchOp)
    ALINK(三十):特征工程(九)特征选择(一)主成分分析(PcaTrainBatchOp/PcaPredictBatchOp)
    ALINK(二十九):特征工程(八)特征组合与交叉(三)Hash Cross特征 (HashCrossFeatureBatchOp)
    ALINK(二十八):特征工程(七)特征组合与交叉(二)Cross特征预测/训练 (CrossFeaturePredictBatchOp)
    ALINK(二十七):特征工程(六)特征组合与交叉(特征组合也叫特征交叉)(一)
    ALINK(二十六):特征工程(五)特征离散化(五)二值化 (BinarizerBatchOp)
  • 原文地址:https://www.cnblogs.com/Ressed/p/10050621.html
Copyright © 2011-2022 走看看