• bzoj 4919 [Lydsy1706月赛]大根堆 set启发式合并+LIS


    4919: [Lydsy1706月赛]大根堆

    Time Limit: 10 Sec  Memory Limit: 256 MB
    Submit: 599  Solved: 260
    [Submit][Status][Discuss]

    Description

    给定一棵n个节点的有根树,编号依次为1到n,其中1号点为根节点。每个点有一个权值v_i。
    你需要将这棵树转化成一个大根堆。确切地说,你需要选择尽可能多的节点,满足大根堆的性质:对于任意两个点i,j,如果i在树上是j的祖先,那么v_i>v_j。
    请计算可选的最多的点数,注意这些点不必形成这棵树的一个连通子树。

    Input

    第一行包含一个正整数n(1<=n<=200000),表示节点的个数。
    接下来n行,每行两个整数v_i,p_i(0<=v_i<=10^9,1<=p_i<i,p_1=0),表示每个节点的权值与父亲。

    Output

    输出一行一个正整数,即最多的点数。

    Sample Input

    6
    3 0
    1 1
    2 1
    3 1
    4 1
    5 1

    Sample Output

    5

    HINT

     

    Source

    本OJ付费获得

    题解:

       因为要维护一个大顶堆,所以就等价于维护每条链都是一个lis的过程,然后合并可以直接用set启发式合并,

       并且模拟LIS过程。

     1 #include<cstring>
     2 #include<cmath>
     3 #include<cstdio>
     4 #include<algorithm>
     5 #include<iostream>
     6 #include<vector>
     7 #include<set>
     8 #include<map>
     9 
    10 #define zz multiset<int>::iterator 
    11 #define ll long long
    12 #define inf 1000000007
    13 #define N 200007
    14 
    15 #define Wb putchar(' ')
    16 #define We putchar('
    ')
    17 #define rg register int
    18 #define fo(i,x,y) for (rg i=x;i<=y;i++)
    19 #define fd(i,x,y) for (rg i=y;i>=x;i--)
    20 #define fb(i,x) for (rg i=x;~i;i=nxt[i])
    21 #define fz(i,x,y) for (zz i=x;i!=y;i++)
    22 #define fi first
    23 #define se second
    24 #define pb(x) push_back(x)
    25 #define SZ(x) ((int)x.size()) 
    26 using namespace std;
    27 inline int read()
    28 {
    29     int x=0,f=1;char ch=getchar();
    30     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    31     while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    32     return x*f;
    33 }
    34 inline void write(ll x)
    35 {
    36     if(x<0) putchar('-'),x=-x;
    37     if (x==0) putchar(48);
    38     int num=0;char c[20];
    39     while(x) c[++num]=(x%10)+48,x/=10;
    40     while(num) putchar(c[num--]);
    41 }
    42 
    43 int n,m;
    44 int a[N];
    45 int cnt,hed[N],rea[N],nxt[N];
    46 multiset<int>s[N];
    47 
    48 void add(int u,int v)
    49 {
    50     nxt[++cnt]=hed[u];
    51     hed[u]=cnt;
    52     rea[cnt]=v;
    53 }
    54 void merge(int x,int y)
    55 {
    56     if (SZ(s[x])>SZ(s[y])) swap(s[x],s[y]);
    57     fz(z,s[x].begin(),s[x].end())
    58         s[y].insert(*z);
    59     s[x].clear();
    60 }
    61 void dfs(int u)
    62 {
    63     fb(i,hed[u])
    64     {
    65         rg v=rea[i];
    66         dfs(v),merge(v,u);
    67     }
    68     zz z=s[u].lower_bound(a[u]);
    69     if (z!=s[u].end()) s[u].erase(z);
    70     s[u].insert(a[u]);
    71 }
    72 int main()
    73 {
    74     memset(hed,-1,sizeof(hed));
    75     n=read();
    76     fo(i,1,n)
    77     {
    78         rg x;
    79         a[i]=read(),x=read();
    80         if (x) add(x,i);
    81     }
    82     dfs(1);
    83     write(s[1].size());
    84 }
  • 相关阅读:
    第0次作业 成绩统计
    助教第一次作业
    二进制协议 vs 文本协议
    Android TimeAnimator && TimeListener翻译
    Android 利用属ObjectAnimator,AnimatorSet性动画绘制一个弹球,加速下落,到底部时挤压,然后减速上弹
    Android使用属性动画ValueAnimator动态改变SurfaceView的背景颜色
    Android 绘制一个Loading动画__向图片中缓慢填充颜色,从而形成动画效果
    at android.view.Surface.unlockCanvasAndPost(Native Method)
    WebView之javascript与android交互基础加强
    WebView之加载网页时增加进度提示
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8983633.html
Copyright © 2020-2023  润新知