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

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

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

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\n", 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 }

转载于:https://www.cnblogs.com/yyf0309/p/6661625.html

UVa 1471 Defense Lines - 线段树 - 离散化相关推荐

  1. uva 1471 Defense Lines

    题目大意:给定一串数字序列,然后叫你删除连续一部分序列,然后使得剩下的序列中存在的连续的最大增长序列长度是多少 . . // // main.cpp // uva UVa1471 Defense Li ...

  2. UVA 1471 Defense Lines 防线 (LIS变形)

    给一个长度为n的序列,要求删除一个连续子序列,使剩下的序列有一个长度最大的连续递增子序列. 最简单的想法是枚举起点j和终点i,然后数一数,分别向前或向后能延伸的最长长度,记为g(i)和f(i).可以先 ...

  3. uva 1471 Defense Lines (降低复杂度)

    题意: 给一个长度为n(n <= 200000) 的序列,你删除一段连续的子序列,使得剩下的序列拼接起来,有一个最长的连续递增子序列 思路: 设f[i] 和g[i] 分别表示 以i为开始 和 以 ...

  4. uva 1471 Defense Lines

    题目:https://vjudge.net/problem/UVA-1471 题意:  lrj思路:第一思路可以暴力枚举,先枚举i(i=1:len),i往右数,看以i开头的最大升序序列个数.然后再枚举 ...

  5. UVA 1471 Defense Lines (LIS变形)

    题意:删除原序列中的一段连续子序列,使得剩下的序列中存在一段最长连续子序列. 题解:LIS变形 我们用l[i]l[i]l[i]和r[i]r[i]r[i]记录往右以iii结尾和往左以iii开头的最长连续 ...

  6. UVA 1471 Defense Lines 防线

    https://vjudge.net/problem/UVA-1471 给一个长度为n的序列,要求删除一个连续子序列,使剩下的序列有一个长度最大的连续递增子序列. 例如  Sample Input 2 ...

  7. UVA - 1471 Defense Lines 贪心+二分

    题目大意:给出长度为n的序列,要求你删除掉一段的连续子序列,使得剩下的序列的递增子序列最长 解题思路:记录以下每个位置的值所能延伸的最左端和最右端,用一个数组记录长度为i的数的最小值,然后从左往右扫描 ...

  8. UVa 1471 Defense Lines (解释紫书思路)

    题目链接:https://cn.vjudge.net/problem/UVA-1471 设序列L表示连续递增子序列: 则最长的L就可以分为两部分,一部分是以j结尾的序列,另一部分是以i为开头的序列 现 ...

  9. UVA 1471 Defense Lines (STL + 二分)

    大体题意: 给你一个长度为n(n < 2e5)的序列,你的任务是删除一个连续的子序列,使得剩下的序列中有一个长度最大的连续递增子序列.求最大序列长度? 思路: 因为要删除一个连续的子序列,所以会 ...

最新文章

  1. cefsharp 发送请求服务器_WEB服务器之HTTP协议
  2. [JAVA基础] 成员变量和局部变量(一看就懂的总结归纳篇)
  3. php可选缓存APC
  4. 支付宝开放新玩法:搜商家可领消费券
  5. 内联元素转化为内联块元素的一些小细节
  6. OpenCV精进之路(三):图像处理——形态学滤波(膨胀、腐蚀、开闭运算)
  7. Java好还是网优好,java和seo哪个好
  8. 容错性设计原则(一)
  9. Java JDK8新特性Lambda表达式
  10. 谷歌google搜索打不开、谷歌gmail邮箱及相关服务无法登录的解决的方法
  11. 利用python模拟ios屏幕点击器_iOS模拟屏幕点击事件
  12. 4万字【Python高级编程】保姆式教学,330页PDF10万字的知识点总结
  13. 英文歌曲:What I Have Done(变形金刚第一部主题曲)
  14. 写大论文的一些注意事项
  15. 工具篇_动软代码生成器
  16. CSDN保存草稿后,在哪里找到草稿
  17. Grafana 的插件开发
  18. matlab gpib硬件实例,GPIB板的安装及使用初步.doc
  19. 用友T3软件中批量输出明细账时科目顺序错乱
  20. COCOS2d_js三消项目基本功能实现

热门文章

  1. Vue-Element-admin 框架上使用 Hiprint 打印插件 一、项目介绍
  2. 苹果ttc转ttf_ttf转ttc字体格式工具 ttctools
  3. java西语_使用Java 8 DateTimeFormatter和西班牙语月份名称进行解析
  4. 读《臧圩人的Java面试题解惑系列》
  5. eclipse java混淆打包,Android Studio和eclipse混淆打包总结
  6. android 代码混淆
  7. 解决cannot resolve directory问题
  8. [HTML5]配置Ngnix服务器支持manifest
  9. 小实操(3): 利用键盘事件实现小人快跑
  10. JavaScript快速入门到高级 JS精品视频课程