zoukankan      html  css  js  c++  java
  • hdu 5748(LIS) Bellovin

    hdu 5748

    Peter有一个序列a1,a2,...,ana_1,a_2,...,a_na1​​,a2​​,...,an​​. 定义F(a1,a2,...,an)=(f1,f2,...,fn)F(a_1,a_2,...,a_n)=(f_1,f_2,...,f_n)F(a1​​,a2​​,...,an​​)=(f1​​,f2​​,...,fn​​), 其中fif_ifi​​是以aia_iai​​结尾的最长上升子序列的长度.
    
    Peter想要找到另一个序列b1,b2,...,bnb_1,b_2,...,b_nb1​​,b2​​,...,bn​​使得F(a1,a2,...,an)F(a_1,a_2,...,a_n)F(a1​​,a2​​,...,an​​)和F(b1,b2,...,bn)F(b_1,b_2,...,b_n)F(b1​​,b2​​,...,bn​​)相同. 对于所有可行的正整数序列, Peter想要那个字典序最小的序列.
    
    序列a1,a2,...,ana_1, a_2, ..., a_na1​​,a2​​,...,an​​比b1,b2,...,bnb_1, b_2, ..., b_nb1​​,b2​​,...,bn​​字典序小, 当且仅当存在一个正整数iii (1≤i≤n)(1 le i le n)(1in)满足对于所有的kkk (1≤k<i)(1 le k < i)(1k<i)都有ak=bka_k = b_kak​​=bk​​并且ai<bia_i < b_iai​​<bi​​.
    输入描述
    输入包含多组数据, 第一行包含一个整数TTT表示测试数据组数. 对于每组数据:
    
    第一行包含一个整数nnn (1≤n≤100000)(1 le n le 100000)(1n100000)表示序列的长度. 第二行包含nnn个整数a1,a2,...,ana_1,a_2,...,a_na1​​,a2​​,...,an​​ (1≤ai≤109)(1 le a_i le 10^9)(1ai​​109​​).
    输出描述
    对于每组数据, 输出nnn个整数b1,b2,...,bnb_1,b_2,...,b_nb1​​,b2​​,...,bn​​ (1≤bi≤109)(1 le b_i le 10^9)(1bi​​109​​)表示那个字典序最小的序列.
    
    输入样例
    3
    1
    10
    5
    5 4 3 2 1
    3
    1 3 5
    输出样例
    1
    1 1 1 1 1
    1 2 3

    就是一个nlgn的求最长上升子序列,比赛的时候脑抽了写了半天线段树

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 using namespace std;
     6 
     7 const int M = 1e5 + 10;
     8 int a[M],b[M],c[M],cas;
     9 
    10 int judge(int x)
    11 {
    12     int l=1,r=cas,ans=1;
    13     while (l<=r)
    14     {
    15         int mid=(l+r)/2;
    16         if (c[mid]>x) r=mid-1,ans=mid;
    17         else if (c[mid]<x) l=mid+1;
    18         else return mid;
    19     }
    20     return ans;
    21 }
    22 
    23 int main()
    24 {
    25     int t,n;
    26     scanf("%d",&t);
    27     while (t--){
    28         scanf("%d",&n);
    29         for (int i=1 ; i<=n ; i++) scanf("%d",&a[i]);
    30         c[1]=a[1];b[1]=1;cas=1;
    31         for (int i=2 ; i<=n ; i++){
    32             if (a[i]<c[1]) c[1]=a[i],b[i]=1;
    33             else if (a[i]>c[cas]) c[++cas]=a[i],b[i]=cas;
    34             else { b[i]=judge(a[i]);c[b[i]]=a[i];}
    35         }
    36         for (int i=1 ; i<n ; i++)
    37             printf("%d ",b[i]);
    38         printf("%d
    ",b[n]);
    39     }
    40 
    41     return 0;
    42 }


  • 相关阅读:
    小知识
    对NSArray中自定义的对象进行排序
    照片浏览滑动效果UIScrollView和UIPageControl组合
    label 设置行间距 字间距
    即使通讯聊天界面搭建----iOS
    ios8推送新增
    UITableviewCell滑动出现多级的控制按钮
    iOS 去掉html标签 留下原本的字符串
    平时常用的小知识点 (不断更新中)
    IOS UI多线程 NSThread 下载并显示图片到UIImageView
  • 原文地址:https://www.cnblogs.com/JJCHEHEDA/p/5704680.html
Copyright © 2011-2022 走看看