zoukankan      html  css  js  c++  java
  • BZOJ3173 [TJOI2013]最长上升子序列

    题面:

    3173: [Tjoi2013]最长上升子序列

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 2108  Solved: 1067
    [Submit][Status][Discuss]

    Description

    给定一个序列,初始为空。现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置。每插入一个数字,我们都想知道此时最长上升子序列长度是多少?

    Input

    第一行一个整数N,表示我们要将1到N插入序列中,接下是N个数字,第k个数字Xk,表示我们将k插入到位置Xk(0<=Xk<=k-1,1<=k<=N)

    Output

    N行,第i行表示i插入Xi位置后序列的最长上升子序列的长度是多少。

    Sample Input

    3
    0 0 2

    Sample Output

    1
    1
    2

    HINT

    100%的数据 n<=100000

    既然插入的数从小到大,我们就可以搞出最终的序列求LIS。

    ans[i]=max{f[j],(1<=j<=i)},f[i]表示插入i后以i为结尾LIS长度。

    只要求出最终序列问题就解决了。

    可以用平衡树(Treap或Splay)

    但是转化为前缀k小后就可以用树状数组求辣!(树状数组求k小值?)

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #include <algorithm>
     5 #include <math.h>
     6 using namespace std;
     7 #define maxn 100001
     8 #define lowbit(x) (x&(-x))
     9 template<typename __>
    10 inline void read(__ &s)
    11 {
    12     char ch;
    13     for(ch=getchar(),s=0;ch<'0'||ch>'9';ch=getchar());
    14     for(;ch>='0'&&ch<='9';s=s*10+ch-'0',ch=getchar());
    15 }
    16 int n;
    17 class fenwick
    18 {
    19     public:
    20         int c[maxn];
    21         void update_sum(int x,int val)
    22         {
    23             for(;x<=n;x+=lowbit(x))
    24                 c[x]+=val;
    25         }
    26         void update_max(int x,int val)
    27         {
    28             for(;x<=n;x+=lowbit(x))
    29                 c[x]=max(c[x],val);
    30         }
    31         int query_kth(int k)
    32         {
    33             int cnt=0,ans=0;
    34             for(int i=17;i>=0;i--)
    35             {
    36                 ans+=(1<<i);
    37                 if(ans>=n||cnt+c[ans]>=k)
    38                     ans-=(1<<i);
    39                 else
    40                     cnt+=c[ans];
    41             }
    42             return ans+1;
    43         }
    44         int query_max(int x)
    45         {
    46             int ans=0;
    47             for(;x;x-=lowbit(x))
    48                 ans=max(ans,c[x]);
    49             return ans;
    50         }
    51 }T;
    52 int QWQ[maxn],QAQ[maxn],f[maxn];
    53 int main()
    54 {
    55     read(n);
    56     for(int i=1;i<=n;i++)
    57     {
    58         read(QWQ[i]);
    59         ++T.c[i];
    60         if((i+lowbit(i))<=n)
    61             T.c[i+lowbit(i)]+=T.c[i];
    62     }
    63     int tmp;
    64     for(int i=n;i>=1;i--)
    65     {
    66         QAQ[tmp=T.query_kth(QWQ[i]+1)]=i;
    67         T.update_sum(tmp,-1);
    68     }
    69     memset(T.c,0,sizeof(T.c));
    70     for(int i=1;i<=n;i++)
    71     {
    72         f[QAQ[i]]=T.query_max(QAQ[i])+1;
    73         T.update_max(QAQ[i],f[QAQ[i]]);
    74     }
    75     for(int i=1;i<=n;i++)
    76         printf("%d
    ",f[i]<f[i-1]?(f[i]=f[i-1]):f[i]);
    77 }
    BZOJ 3173
  • 相关阅读:
    OpenGL学习之路(四)
    OpenGL学习之路(三)
    ajax请求成功后新开窗口window.open()被拦截解决方法
    Mysql日志解析
    Kibana+Logstash+Elasticsearch 日志查询系统
    谈谈Redis的SETNX
    常用前端开发工具合集
    Media Queries 详解
    启动mysql时显示:/tmp/mysql.sock 不存在的解决方法
    找不到mysql.sock,mysql.sock丢失问题解决方法
  • 原文地址:https://www.cnblogs.com/radioteletscope/p/7762177.html
Copyright © 2011-2022 走看看