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
  • 相关阅读:
    Core 1.0中的管道-中间件模式
    java平台的常用资源
    C#设备处理类操作
    C#语音录制
    Web中的性能优化
    nginx+lua+redis构建高并发应用(转)
    HttpLuaModule——翻译(Nginx API for Lua) (转)
    Nginx各版本的区别
    Linux(Centos)中tcpdump参数用法详解(转)
    我见过最好的vsftpd配置教程(转)
  • 原文地址:https://www.cnblogs.com/DriverLao/p/9714116.html
Copyright © 2011-2022 走看看