zoukankan      html  css  js  c++  java
  • LightOJ 1277 Looking for a Subsequence

    http://www.lightoj.com/volume_problemstat.php?problem=1277

      LightOJ搞得挺漂亮的,第一次到那里交题,挺喜欢的。

      线段树统计题,题意是:给出一行数,找到所要求的长度的单调上升子序列,并输出该序列。

      这题我是先从后往前,求出到达某个位置的时候,最长可以构建出多长的单调上升子序列。这是一个dp问题,不过用dp方法复杂度是O(n^2)会超时,所以我用线段树来降低查找的复杂度。题目比较简单,不过数据范围较大,所以要用hash来离散化处理。最后回溯一下就可以搜索出目标序列了!

    代码如下:

    View Code
      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 #include <vector>
      5 #include <cstring>
      6 
      7 using namespace std;
      8 
      9 typedef vector<int> vi;
     10 const int hashSize = 400009;
     11 const int HASH = 0x55555555;
     12 int hash[hashSize], hashPos[hashSize];
     13 vi buf, X;
     14 
     15 void insHash(int x, int pos) {
     16     int p = (x ^ HASH) % hashSize;
     17 
     18     if (p < 0) p += hashSize;
     19     while (hash[p] != x && ~hashPos[p]) {
     20         p++;
     21         if (p >= hashSize) p -= hashSize;
     22     }
     23 
     24     hash[p] = x;
     25     hashPos[p] = pos;
     26 }
     27 
     28 int getPos(int x) {
     29     int p = (x ^ HASH) % hashSize;
     30 
     31     if (p < 0) p += hashSize;
     32     while (hash[p] != x && ~hashPos[p]) {
     33         p++;
     34         if (p >= hashSize) p -= hashSize;
     35     }
     36 
     37     return hashPos[p];
     38 }
     39 
     40 void initHash() {
     41     memset(hashPos, -1, sizeof(hashPos));
     42 }
     43 
     44 void scan(int &x) {
     45     char c;
     46 
     47     for ( ; ((c = getchar()) < '0' || c > '9') && c != '-'; ) ;
     48     if (c != '-') for (x = c - '0'; '0' <= (c = getchar()) && c <= '9'; x = x * 10 + c - '0') ;
     49     else for (x = 0; '0' <= (c = getchar()) && c <= '9'; x = x * 10 + '0' - c) ;
     50 }
     51 
     52 int treeSize;
     53 
     54 void input(int n) {
     55     int x;
     56 
     57     X.clear();
     58     buf.clear();
     59     initHash();
     60 
     61     while (n--) {
     62         scan(x);
     63         X.push_back(x);
     64         buf.push_back(x);
     65     }
     66     sort(X.begin(), X.end());
     67 
     68     int endi = unique(X.begin(), X.end()) - X.begin();
     69 
     70     treeSize = endi;
     71     for (int i = 0; i < endi; i++) {
     72         insHash(X[i], i);
     73     }
     74 }
     75 
     76 #define lson l, m, rt << 1
     77 #define rson m + 1, r, rt << 1 | 1
     78 #define ROOT 0, treeSize - 1, 1
     79 
     80 const int maxn = 100001;
     81 int mx[maxn << 2];
     82 
     83 void build(int l, int r, int rt) {
     84     mx[rt] = 0;
     85     if (l == r) return ;
     86 
     87     int m = (l + r) >> 1;
     88 
     89     build(lson);
     90     build(rson);
     91     mx[rt] = max(mx[rt << 1], mx[rt << 1 | 1]);
     92 }
     93 
     94 void update(int p, int x, int l, int r, int rt) {
     95     if (l == r) {
     96         mx[rt] = max(mx[rt], x);
     97         return ;
     98     }
     99     int m = (l + r) >> 1;
    100 
    101     if (p <= m) update(p, x, lson);
    102     else update(p, x, rson);
    103     mx[rt] = max(mx[rt << 1], mx[rt << 1 | 1]);
    104 }
    105 
    106 int query(int L, int R, int l, int r, int rt) {
    107     if (L <= l && r <= R) {
    108         return mx[rt];
    109     }
    110     int m = (l + r) >> 1;
    111 
    112     if (L <= m) {
    113         if (m < R) {
    114             return max(query(L, R, lson), query(L, R, rson));
    115         } else {
    116             return query(L, R, lson);
    117         }
    118     }
    119     if (m < R) {
    120         return query(L, R, rson);
    121     }
    122 }
    123 
    124 int maxLen[maxn];
    125 
    126 void deal(int n, int m) {
    127     input(n);
    128     build(ROOT);
    129     for (int i = n - 1; i >= 0; i--) {
    130         int pos = getPos(buf[i]) + 1;
    131 
    132 //        printf("~%d\n", pos);
    133         if (pos < treeSize) {
    134             maxLen[i] = query(pos, treeSize - 1, ROOT) + 1;
    135             update(pos - 1, maxLen[i], ROOT);
    136         } else {
    137             maxLen[i] = 1;
    138             update(pos - 1, maxLen[i], ROOT);
    139         }
    140 //        printf("%d ", maxLen[i]);
    141     }
    142 //    puts("~~~");
    143 
    144     while (m--) {
    145         int x, i = 0;
    146 
    147         scan(x);
    148         while (i < n) {
    149             if (maxLen[i] >= x) break;
    150             i++;
    151         }
    152         if (i >= n) puts("Impossible");
    153         else {
    154             int last = buf[i];
    155 
    156             printf("%d", buf[i]);
    157             x--;
    158             i++;
    159             while (x) {
    160                 if (maxLen[i] >= x && buf[i] > last) {
    161                     printf(" %d", buf[i]);
    162                     x--;
    163                     last = buf[i];
    164                 }
    165                 i++;
    166             }
    167             puts("");
    168         }
    169     }
    170 }
    171 
    172 int main() {
    173     int n, m;
    174     int T;
    175 
    176 //    freopen("in", "r", stdin);
    177     scan(T);
    178     for (int i = 1; i <= T; i++) {
    179         printf("Case %d:\n", i);
    180         scan(n);
    181         scan(m);
    182         deal(n, m);
    183     }
    184 
    185     return 0;
    186 }

    ——written by Lyon

  • 相关阅读:
    minGw编译器记录
    也来小谈jsonP
    [struts2]2.3.14 jsonplugin 存在bug<java.lang.NoSuchFieldException: DEFAULT_PARAM>
    年学习进度简记【2012】
    征服ExtJs那棵树(ExtJs官方开发手册汉语详解TreePanel)
    html 和ExtJs 搭建背景音乐 开发
    复习整理2
    MSChartHelpe
    DataToExcel
    如何将一个类型在FOREACH中使用
  • 原文地址:https://www.cnblogs.com/LyonLys/p/loj_1277_Lyon.html
Copyright © 2011-2022 走看看