zoukankan      html  css  js  c++  java
  • Hdu 3564 Another LIS 线段树+LIS

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 1361    Accepted Submission(s): 492


    Problem Description
    There is a sequence firstly empty. We begin to add number from 1 to N to the sequence, and every time we just add a single number to the sequence at a specific position. Now, we want to know length of the LIS (Longest Increasing Subsequence) after every time's add.
     
    Input
    An integer T (T <= 10), indicating there are T test cases.
    For every test case, an integer N (1 <= N <= 100000) comes first, then there are N numbers, the k-th number Xk means that we add number k at position Xk (0 <= Xk <= k-1).See hint for more details.
     
    Output
    For the k-th test case, first output "Case #k:" in a separate line, then followed N lines indicating the answer. Output a blank line after every test case.
     
    Sample Input
    1
    3
    0 0 2
     
    Sample Output
    Case #1:
    1
    1
    2
    Hint
    In the sample, we add three numbers to the sequence, and form three sequences. a. 1 b. 2 1 c. 2 1 3
     
    Author
    standy
     
    Source
     
    思路:由于是从大到小插值的,那么我们只需要知道最终的序列,再对其求一遍LIS即可。可以用线段树求最终的序列,从后往前考虑,一开始有n个空位,对于每个数的插入位置a[i],其应该放在从左往右的第a[i]个空格,放完数后该空格被占用。该问题相当于给出n个数,多次操作,找出第k1个数后,将该数删去,继续找第k2个数。。。
    #include <bits/stdc++.h>
    using namespace std;
    const int N = 100000 + 5;
    #define lson rt << 1, l, m
    #define rson rt <<1|1, m + 1, r
    
    int num[N << 2];
    int a[N], pos[N], ans[N], res[N], n;
    void build(int rt, int l, int r) {
        num[rt] = r - l + 1;
        if(l == r) return ;
        int m = (l + r) >> 1;
        build(lson);
        build(rson);
    }
    void update(int rt, int l, int r, int k, int v) {
        if(l == r) {
            pos[l] = v;
            num[rt] = 0;
            return;
        }
        int m = (l + r) >> 1;
        if(k > num[rt << 1]) update(rson, k - num[rt << 1], v);
        else                 update(lson, k, v);
        num[rt] = num[rt << 1] + num[rt << 1|1];
    }
    int LIS[N], len;
    void solve() {
        len = 1;
        LIS[0] = 0;
        for(int i = 1; i <= n; ++i) {
            int p = upper_bound(LIS, LIS + len, pos[i]) - LIS - 1;
            LIS[p + 1] = pos[i];
            ans[i] = p + 1;
            if(p + 1 == len) len++;
        }
    }
    int main() {
       // freopen("in.txt", "r", stdin);
        int _, cas = 1; scanf("%d", &_);
        while(_ --) {
            scanf("%d", &n);
            build(1, 1, n);
           // puts("-----BUG-----");
    
            for(int i = 1; i <= n; ++i) { scanf("%d", a + i); a[i]++; }
            for(int i = n; i >= 1; --i) update(1, 1, n, a[i], i);
            solve();
            for(int i = 1; i <= n; ++i) res[ pos[i] ] = ans[i];
            for(int i = 2; i <= n; ++i) res[i] = max(res[i], res[i - 1]);
            printf("Case #%d:
    ", cas++);
            for(int i = 1; i <= n; ++i) printf("%d
    ", res[i]);
            puts("");
        }
    }
    View Code
  • 相关阅读:
    servlet 传值和取值问题
    .net 获取存储过程返回值和Output输出参数值
    游标使用
    java中直接根据Date获取明天的日期
    Linux通配符与特殊符号知识大全
    zabbix监控
    KVM介绍 虚拟化简史
    GFS文件系统
    Oracle JOB定时器
    IDEA JSP 不能使用EL表达式
  • 原文地址:https://www.cnblogs.com/orchidzjl/p/5487770.html
Copyright © 2011-2022 走看看