• bzoj4458 GTY的OJ (优先队列+倍增)


    超级钢琴放到了树上。

    这次不用主席树了..本来以为会好写一点没想到细节更多(其实是树上细节多)

    为了方便,对每个点把他的那个L,R区间转化成两个深度a,b,表示从[a,b)选一个最小的前缀和(到根的和)减掉

    为了更加方便,编号变为2~N+1,然后把2连到1上,1作为一个假根,权值为0

    然后倍增去找那个a和b,记一记最小值的位置,然后劈开再加回到优先队列里就行了

     1 #include<bits/stdc++.h>
     2 #define pa pair<int,int>
     3 #define CLR(a,x) memset(a,x,sizeof(a))
     4 using namespace std;
     5 typedef long long ll;
     6 const int maxn=5e5+10;
     7 const ll inf=1e12;
     8 
     9 inline ll rd(){
    10     ll x=0;char c=getchar();int neg=1;
    11     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
    12     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
    13     return x*neg;
    14 }
    15 
    16 struct Node{
    17     int x,l,r,m;ll v;
    18 };
    19 bool operator < (Node a,Node b){return a.v<b.v;}
    20 bool operator > (Node a,Node b){return a.v>b.v;}
    21 int N,M,L,R;
    22 int fa[maxn][22],mi[maxn][22],dep[maxn];
    23 ll mn[maxn][22],v[maxn];
    24 priority_queue<Node> q;
    25 
    26 inline ll getrmq(int x,int l,int r,int &m){
    27     if(l<=0) return -inf;
    28     ll vx=v[x];
    29     for(int i=19;i>=0;i--){
    30         if(fa[x][i]&&dep[fa[x][i]]>=l)
    31             x=fa[x][i];
    32     }
    33     ll f=inf;
    34     for(int i=19;i>=0;i--){
    35         if(fa[x][i]&&dep[fa[x][i]]>=r){
    36             if(mn[x][i]<f) f=mn[x][i],m=dep[mi[x][i]];
    37             x=fa[x][i];
    38         }
    39     }
    40     if(dep[x]>r&&mn[x][0]<f) f=mn[x][0],m=dep[mi[x][0]];
    41     // printf("%d %d
    ",vx,f);
    42     return vx-f;
    43 }
    44 
    45 int main(){
    46     //freopen("","r",stdin);
    47     int i,j,k;
    48     N=rd();
    49     for(i=2;i<=N+1;i++){
    50         fa[i][0]=rd()+1;
    51     }dep[1]=1;
    52     for(i=2;i<=N+1;i++) v[i]=v[fa[i][0]]+rd(),dep[i]=dep[fa[i][0]]+1;
    53     M=rd(),L=rd(),R=rd();
    54 
    55     for(i=1;i<=N+1;i++){
    56         mn[i][0]=v[i],mi[i][0]=i;
    57         for(j=0;fa[i][j]&&fa[fa[i][j]][j];j++){
    58             fa[i][j+1]=fa[fa[i][j]][j];
    59             if(mn[i][j]<mn[fa[i][j]][j]) mn[i][j+1]=mn[i][j],mi[i][j+1]=mi[i][j];
    60             else mn[i][j+1]=mn[fa[i][j]][j],mi[i][j+1]=mi[fa[i][j]][j];
    61         }
    62     }
    63     for(i=2;i<=N+1;i++){
    64         Node p;
    65         p.x=i,p.l=dep[i]-L,p.r=dep[i]-R-1;
    66         // printf("%d %d %d
    ",p.x,p.l,p.r);
    67         if(p.l<=0) continue;
    68         p.v=getrmq(p.x,p.l,p.r,p.m);
    69         q.push(p);
    70     }
    71     ll ans=0;
    72     for(i=1;i<=M;i++){
    73         Node p=q.top();q.pop();
    74         ans+=p.v;
    75         if(p.m<p.l){
    76             Node p1;
    77             p1.x=p.x,p1.l=p.l,p1.r=p.m;
    78             p1.v=getrmq(p1.x,p1.l,p1.r,p1.m);
    79             q.push(p1);
    80         }if(p.r<p.m-1){
    81             Node p2;
    82             p2.x=p.x,p2.l=p.m-1,p2.r=p.r;
    83             p2.v=getrmq(p2.x,p2.l,p2.r,p2.m);
    84             q.push(p2);
    85         }
    86     }
    87     printf("%lld
    ",ans);
    88     return 0;
    89 }
  • 相关阅读:
    Nginx Mac笔记
    当一个女人门外有一个流氓时,她该做什么
    图片圆角并居中显示解决方案
    caffe源码学习之Proto数据格式【1】
    google gflag使用方法举例
    降维之pca算法
    聚类之dbscan算法
    ubuntu 使用sudo apt-get update 出现 被配置多次导致无法升级错误解决方法
    关于python使用threadpool中的函数单个参数和多个参数用法举例
    python科学计算之numpy
  • 原文地址:https://www.cnblogs.com/Ressed/p/9758745.html
Copyright © 2020-2023  润新知