zoukankan      html  css  js  c++  java
  • 洛谷P1552 [APIO2012]派遣(左偏树)

    传送门

    做这题的时候现学了一波左偏树2333(好吧其实是当初打完板子就给忘了)

    不难发现肯定是选子树里权值最小的点且选得越多越好

    但如果在每一个点维护一个小根堆,我们得一直找知道权值大于m为止,时间会炸

    于是我们对每一个点维护一个大根堆,一直pop直到堆里总的权值小于m为止,此时堆里的元素个数就是总共的人数

    不难发现每一个人最多只会被pop一次,于是时间复杂度就是$O(n logn)$

    左偏树合并写错了竟然还能有67分……

     1 //minamoto
     2 #include<bits/stdc++.h>
     3 #define ll long long
     4 using namespace std;
     5 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
     6 char buf[1<<21],*p1=buf,*p2=buf;
     7 template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
     8 inline int read(){
     9     #define num ch-'0'
    10     char ch;bool flag=0;int res;
    11     while(!isdigit(ch=getc()))
    12     (ch=='-')&&(flag=true);
    13     for(res=num;isdigit(ch=getc());res=res*10+num);
    14     (flag)&&(res=-res);
    15     #undef num
    16     return res;
    17 }
    18 const int N=1e5+5;
    19 int head[N],Next[N],ver[N],tot;
    20 inline void add(int u,int v){
    21     ver[++tot]=v,Next[tot]=head[u],head[u]=tot;
    22 }
    23 int val[N],rt[N],L[N],R[N],a[N],d[N],sz[N],n,m;ll sum[N],ans;
    24 int merge(int x,int y){
    25     if(!x||!y) return x+y;
    26     if(val[x]<val[y]) swap(x,y);
    27     R[x]=merge(R[x],y);
    28     if(d[R[x]]>d[L[x]]) swap(L[x],R[x]);
    29     d[x]=d[R[x]]+1;return x;
    30 }
    31 void dfs(int u){
    32     sz[u]=1,sum[u]=val[u],rt[u]=u;
    33     for(int i=head[u];i;i=Next[i]){
    34         int v=ver[i];dfs(v);
    35         sz[u]+=sz[v],sum[u]+=sum[v],rt[u]=merge(rt[u],rt[v]);
    36     }
    37     while(sum[u]>m&&sz[u]){
    38         sum[u]-=val[rt[u]],--sz[u],rt[u]=merge(L[rt[u]],R[rt[u]]);
    39     }
    40     cmax(ans,1ll*sz[u]*a[u]);
    41 }
    42 int main(){
    43 //    freopen("testdata.in","r",stdin);
    44     n=read(),m=read();
    45     for(int i=1;i<=n;++i){
    46         int fa=read();val[i]=read(),a[i]=read();
    47         add(fa,i);
    48     }
    49     dfs(1);
    50     printf("%lld
    ",ans);
    51     return 0;
    52 }
  • 相关阅读:
    Quartz.Net系列(二):介绍、简单使用、对比Windows计划任务
    Quartz.Net系列(一):Windows任务计划程序
    Linux下swap到底有没有必要使用
    Linux服务器有大量的TIME_WAIT状态
    HTTP请求头中的X-Forwarded-For介绍
    Keepalived实现服务高可用
    Gitlab常规操作
    Git 常用命令
    HTTP常见状态码
    《Docker从入门到跑路》之多阶段构建
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9806184.html
Copyright © 2011-2022 走看看