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 }


  • 相关阅读:
    GitLab 介绍
    git 标签
    git 分支
    git 仓库 撤销提交 git reset and 查看本地历史操作 git reflog
    git 仓库 回退功能 git checkout
    python 并发编程 多进程 练习题
    git 命令 查看历史提交 git log
    git 命令 git diff 查看 Git 区域文件的具体改动
    POJ 2608
    POJ 2610
  • 原文地址:https://www.cnblogs.com/JJCHEHEDA/p/5704680.html
Copyright © 2011-2022 走看看