zoukankan      html  css  js  c++  java
  • BZOJ 4919 [Lydsy1706月赛]大根堆 (SRM08 T3)

    【题解】

      求一个序列的LIS有一个二分做法是这样的:f[i]表示长度为i的上升序列中最后一个数最小可以是多少,每次二分大于等于当前数字x的f[j],把f[j]修改为x;如果找不到这样的f[j],那就把长度加一并记录新的f(即f[++len]=x)

      现在我们把这个做法放到树上,同样是可以做的。我们用set维护子树内的f数组,父节点在其孩子合并得到的set中二分第一个大于等于它的数字,换成父节点自己的值。合并子树的set直接启发式合并即可。两个log的复杂度。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<set>
     5 #define N 200010
     6 #define rg register
     7 #define LL long long
     8 using namespace std;
     9 int n,tot,last[N],val[N];
    10 multiset<int>f[N];
    11 struct edge{
    12     int to,pre;
    13 }e[N];
    14 inline int read(){
    15     int k=0,f=1; char c=getchar();
    16     while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
    17     while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
    18     return k*f;
    19 }
    20 void dfs(int x,int fa){
    21     for(rg int i=last[x],to;i;i=e[i].pre){
    22         dfs(to=e[i].to,x);
    23         if(f[to].size()>f[x].size()) swap(f[x],f[to]);
    24         for(set<int>::iterator j=f[to].begin();j!=f[to].end();j++) f[x].insert(*j);
    25         f[to].clear();
    26     }
    27     if(f[x].size()>0&&f[x].lower_bound(val[x])!=f[x].end()) f[x].erase(f[x].lower_bound(val[x]));
    28     f[x].insert(val[x]);
    29 }
    30 int main(){
    31     n=read();
    32     for(rg int i=1;i<=n;i++){
    33         val[i]=read(); int fa=read();
    34         e[++tot]=(edge){i,last[fa]}; last[fa]=tot;
    35     }
    36     dfs(1,0);
    37     printf("%d
    ",f[1].size());
    38     return 0;
    39 }
    View Code
  • 相关阅读:
    翻译:关于Evaluation Stack
    beanshell 响应数据的解析与变量的保存
    nmon 采坑
    linux 防火墙管理
    服务器 安装docker (启动坑了很久才成功)docker-compose
    数据库负载均衡 happroxy 中间器(Nginx)容器的安装与配置
    docker 中搭建 mysql pxc 集群
    字节面试
    中缀表达式转为后缀表达式
    SpringBoot解决thymeleaf引入公共部分问题
  • 原文地址:https://www.cnblogs.com/DriverLao/p/9714116.html
Copyright © 2011-2022 走看看