• UVa 1471 Defense Lines



      题意是说给一个序列,删掉其中一段连续的子序列(貌似可以为空),使得新的序列中最长的连续递增子序列最长。

      网上似乎最多的做法是二分查找优化,然而不会,只会值域线段树和离散化。。。

      先预处理出所有的点所能延伸到最左端的长度,和到最右端的长度,然后离散化,然后对于当前的点,就交给值域线段树去查出前面最大的符合条件的向左延伸的长度,加上当前位置最大向右延伸的长度,更新答案即可。

    Code

      1 /**
      2  * UVa
      3  * Problem#1471
      4  * Accepted
      5  * Time:1190ms
      6  */
      7 #include<iostream>
      8 #include<cstdio>
      9 #include<cctype>
     10 #include<ctime>
     11 #include<cstring>
     12 #include<cstdlib>
     13 #include<fstream>
     14 #include<sstream>
     15 #include<algorithm>
     16 #include<map>
     17 #include<set>
     18 #include<stack>
     19 #include<queue>
     20 #include<vector>
     21 #include<stack>
     22 using namespace std;
     23 typedef bool boolean;
     24 #define inf 0xfffffff
     25 #define smin(a, b) a = min(a, b)
     26 #define smax(a, b) a = max(a, b)
     27 template<typename T>
     28 inline void readInteger(T& u){
     29     char x;
     30     int aFlag = 1;
     31     while(!isdigit((x = getchar())) && x != '-');
     32     if(x == '-'){
     33         x = getchar();
     34         aFlag = -1;
     35     }
     36     for(u = x - '0'; isdigit((x = getchar())); u = (u << 1) + (u << 3) + x - '0');
     37     ungetc(x, stdin);
     38     u *= aFlag;
     39 }
     40 
     41 typedef class SegTreeNode {
     42     public:
     43         int val;
     44         SegTreeNode *l, *r;
     45         SegTreeNode(int val = 0, SegTreeNode* l = NULL, SegTreeNode* r = NULL):val(val), l(l), r(r) {        }
     46 
     47         inline void pushUp() {
     48             val = max(l->val, r->val);
     49         }
     50 }SegTreeNode;
     51 
     52 typedef class SegTree {
     53     public:
     54         SegTreeNode* root;
     55         SegTree():root(NULL) {        }
     56         SegTree(int s) {
     57             build(root, 1, s);
     58         }
     59         
     60         void build(SegTreeNode*& node, int l, int r) {
     61             node = new SegTreeNode();
     62             if(l == r)    return;
     63             int mid = (l + r) >> 1;
     64             build(node->l, l, mid);
     65             build(node->r, mid + 1, r);
     66         }
     67         
     68         void update(SegTreeNode*& node, int l, int r, int idx, int val) {
     69             if(l == idx && r == idx) {
     70                 smax(node->val, val);
     71                 return;
     72             }
     73             int mid = (l + r) >> 1;
     74             if(idx <= mid)    update(node->l, l, mid, idx, val);
     75             else    update(node->r, mid + 1, r, idx, val);
     76             node->pushUp();
     77         }
     78         
     79         int query(SegTreeNode*& node, int l, int r, int ql, int qr) {
     80             if(qr < ql)    return -inf;
     81             if(l == ql && r == qr) {
     82                 return node->val;
     83             }
     84             int mid = (l + r) >> 1;
     85             if(qr <= mid)    return query(node->l, l, mid, ql, qr);
     86             if(ql > mid)    return query(node->r, mid - 1, r, ql, qr);
     87             int sl = query(node->l, l, mid, ql, mid);
     88             int sr = query(node->r, mid + 1, r, mid + 1, qr);
     89             return max(sl, sr);
     90         }
     91         
     92         inline void clear(SegTreeNode*& node) {
     93             if(node == NULL)    return;
     94             clear(node->l);
     95             clear(node->r);
     96             delete[] node;
     97         }
     98 }SegTree;
     99 
    100 int T;
    101 int n;
    102 int len;
    103 int* lis;
    104 int* buf;
    105 SegTree st;
    106 
    107 inline void init() {
    108     readInteger(n);
    109     lis = new int[(const int)(n + 1)];
    110     buf = new int[(const int)(n + 1)];
    111     for(int i = 1; i <= n; i++)
    112         readInteger(lis[i]);
    113 }
    114 
    115 inline void descreate(int* a) {
    116     memcpy(buf, a, sizeof(int) * (n + 1));
    117     sort(buf + 1, buf + n + 1);
    118     len = unique(buf + 1, buf + n + 1) - buf;
    119     for(int i = 1; i <= n; i++)
    120         a[i] = lower_bound(buf + 1, buf + len, a[i]) - buf;
    121 }
    122 
    123 int *tol, *tor;
    124 inline void dp() {
    125     tol = new int[(const int)(n + 1)];
    126     tor = new int[(const int)(n + 1)];
    127     tol[1] = 1;
    128     for(int i = 2; i <= n; i++)
    129         tol[i] = (lis[i] > lis[i - 1]) ? (tol[i - 1] + 1) : (1);
    130     tor[n] = 1;
    131     for(int i = n - 1; i > 0; i--)
    132         tor[i] = (lis[i] < lis[i + 1]) ? (tor[i + 1] + 1) : (1);
    133 }
    134 
    135 int result;
    136 inline void solve() {
    137     result = 1;
    138     descreate(lis);
    139     st = SegTree(len);
    140     dp();
    141 //    st.update(st.root, 1, len, lis[1], tol[1]);
    142     for(int i = 1; i <= n; i++) {
    143         int c = st.query(st.root, 1, len, 1, lis[i] - 1);
    144         smax(result, c + tor[i]);
    145         st.update(st.root, 1, len, lis[i], tol[i]);
    146     }
    147     printf("%d
    ", result);
    148     delete[] tol;
    149     delete[] tor;
    150     delete[] buf;
    151     delete[] lis;
    152     st.clear(st.root);
    153 }
    154 
    155 int main() {
    156     readInteger(T);
    157     while(T--) {
    158         init();
    159         solve();
    160     }
    161     return 0;
    162 }
  • 相关阅读:
    树的同构
    最大子列和
    多项式的表示和运算
    图1
    集合及运算
    树4
    树3
    树2
    期末作业验收
    个人总结
  • 原文地址:https://www.cnblogs.com/yyf0309/p/6661625.html
Copyright © 2020-2023  润新知