• bzoj3173 最长上升子序列 树状数组


    链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3173

    题意:向序列中动态插入$1~n$排列元素,求出插入每个元素后最长上升子序列长度。

    如Claris所言,面对这种数据结构,必有高论。如果只想着数据结构,我们可以通过平衡树动态维护序列,同时使用树状数组计算最长上升子序列。

    但是我们不是猩猩不是数据结构狂人,我们毕竟还是要本着能不上树就不上树能少用数据结构就少用的原则来设计算法的。

    重新考虑这个题目。本题没有要求强制在线,于是我们把整个操作倒过来看,于是问题就变成了不停地删去序列中某个元素后求出当前最长上升子序列长度。

    然后,不要忘了一个重要条件:这个东西是从小到大插入的。

    从小到大插入,意味着插入一个数之后最长上升子序列发生变化的唯一可能就是以这个数结尾。

    那么我们就维护一下删掉每个数之前以这个数结尾的最长上升子序列就好了,最后输出答案时,将这个与前一个比较,短就直接将当前这个数赋值成为上一个。

    说得简单……但是这道题真的是一个树状数组综合运用……具体看代码吧……

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 using namespace std;
     6 int lowbit(int x)
     7 {
     8     return x&(-x);
     9 }
    10 const int maxn=100005;
    11 int C[maxn],n;
    12 void Modify(int pos,int val)
    13 {
    14     for(;pos<=n;pos+=lowbit(pos))C[pos]+=val;
    15 }
    16 void Maximum(int pos,int val)
    17 {
    18     for(;pos<=n;pos+=lowbit(pos))C[pos]=max(C[pos],val);
    19 }
    20 int Query_kth(int k)
    21 {
    22     int cnt=0,ans=0;
    23     for(int i=17;~i;i--)
    24     {
    25         ans+=(1<<i);
    26         if(ans>=n||cnt+C[ans]>=k)ans-=(1<<i);
    27         else cnt+=C[ans];
    28     }
    29     return ans+1;
    30 }
    31 int Query_max(int pos)
    32 {
    33     int res=0;
    34     for(;pos;pos-=lowbit(pos))res=max(res,C[pos]);
    35     return res;
    36 }
    37 int a[maxn],b[maxn],f[maxn];
    38 int haha()
    39 {
    40     scanf("%d",&n);
    41     for(int i=1;i<=n;i++)
    42     {
    43         scanf("%d",&a[i]);C[i]++;
    44         if((i+lowbit(i))<=n)C[i+lowbit(i)]+=C[i];
    45     }
    46     int tmp;
    47     for(int i=n;i;i--)b[tmp=Query_kth(a[i]+1)]=i,Modify(tmp,-1);
    48     memset(C,0,sizeof(C));
    49     for(int i=1;i<=n;i++)f[b[i]]=Query_max(b[i])+1,Maximum(b[i],f[b[i]]);
    50     for(int i=1;i<=n;i++)printf("%d
    ",f[i]<f[i-1]?(f[i]=f[i-1]):f[i]);
    51 }
    52 int sb=haha();
    53 int main(){;}
    bzoj3173
  • 相关阅读:
    C# 反射设置属性帮助类
    WPF xaml中写代码
    redis 击穿、穿透、雪崩产生原因及解决方案
    Linux环境安装Tengine
    lsof使用说明
    Delve调试器简单使用说明
    web访问日志分析
    MongoDB中文社区 Freetalk,一起来玩快闪!
    在线研讨会:实时数据同步应用场景及实现方案探讨
    labview使用百度地图API,报错getContext方法未定义
  • 原文地址:https://www.cnblogs.com/Loser-of-Life/p/7780435.html
Copyright © 2020-2023  润新知