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\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 - 线段树 - 离散化相关推荐
- uva 1471 Defense Lines
题目大意:给定一串数字序列,然后叫你删除连续一部分序列,然后使得剩下的序列中存在的连续的最大增长序列长度是多少 . . // // main.cpp // uva UVa1471 Defense Li ...
- UVA 1471 Defense Lines 防线 (LIS变形)
给一个长度为n的序列,要求删除一个连续子序列,使剩下的序列有一个长度最大的连续递增子序列. 最简单的想法是枚举起点j和终点i,然后数一数,分别向前或向后能延伸的最长长度,记为g(i)和f(i).可以先 ...
- uva 1471 Defense Lines (降低复杂度)
题意: 给一个长度为n(n <= 200000) 的序列,你删除一段连续的子序列,使得剩下的序列拼接起来,有一个最长的连续递增子序列 思路: 设f[i] 和g[i] 分别表示 以i为开始 和 以 ...
- uva 1471 Defense Lines
题目:https://vjudge.net/problem/UVA-1471 题意: lrj思路:第一思路可以暴力枚举,先枚举i(i=1:len),i往右数,看以i开头的最大升序序列个数.然后再枚举 ...
- UVA 1471 Defense Lines (LIS变形)
题意:删除原序列中的一段连续子序列,使得剩下的序列中存在一段最长连续子序列. 题解:LIS变形 我们用l[i]l[i]l[i]和r[i]r[i]r[i]记录往右以iii结尾和往左以iii开头的最长连续 ...
- UVA 1471 Defense Lines 防线
https://vjudge.net/problem/UVA-1471 给一个长度为n的序列,要求删除一个连续子序列,使剩下的序列有一个长度最大的连续递增子序列. 例如 Sample Input 2 ...
- UVA - 1471 Defense Lines 贪心+二分
题目大意:给出长度为n的序列,要求你删除掉一段的连续子序列,使得剩下的序列的递增子序列最长 解题思路:记录以下每个位置的值所能延伸的最左端和最右端,用一个数组记录长度为i的数的最小值,然后从左往右扫描 ...
- UVa 1471 Defense Lines (解释紫书思路)
题目链接:https://cn.vjudge.net/problem/UVA-1471 设序列L表示连续递增子序列: 则最长的L就可以分为两部分,一部分是以j结尾的序列,另一部分是以i为开头的序列 现 ...
- UVA 1471 Defense Lines (STL + 二分)
大体题意: 给你一个长度为n(n < 2e5)的序列,你的任务是删除一个连续的子序列,使得剩下的序列中有一个长度最大的连续递增子序列.求最大序列长度? 思路: 因为要删除一个连续的子序列,所以会 ...
最新文章
- cefsharp 发送请求服务器_WEB服务器之HTTP协议
- [JAVA基础] 成员变量和局部变量(一看就懂的总结归纳篇)
- php可选缓存APC
- 支付宝开放新玩法:搜商家可领消费券
- 内联元素转化为内联块元素的一些小细节
- OpenCV精进之路(三):图像处理——形态学滤波(膨胀、腐蚀、开闭运算)
- Java好还是网优好,java和seo哪个好
- 容错性设计原则(一)
- Java JDK8新特性Lambda表达式
- 谷歌google搜索打不开、谷歌gmail邮箱及相关服务无法登录的解决的方法
- 利用python模拟ios屏幕点击器_iOS模拟屏幕点击事件
- 4万字【Python高级编程】保姆式教学,330页PDF10万字的知识点总结
- 英文歌曲:What I Have Done(变形金刚第一部主题曲)
- 写大论文的一些注意事项
- 工具篇_动软代码生成器
- CSDN保存草稿后,在哪里找到草稿
- Grafana 的插件开发
- matlab gpib硬件实例,GPIB板的安装及使用初步.doc
- 用友T3软件中批量输出明细账时科目顺序错乱
- COCOS2d_js三消项目基本功能实现
热门文章
- Vue-Element-admin 框架上使用 Hiprint 打印插件 一、项目介绍
- 苹果ttc转ttf_ttf转ttc字体格式工具 ttctools
- java西语_使用Java 8 DateTimeFormatter和西班牙语月份名称进行解析
- 读《臧圩人的Java面试题解惑系列》
- eclipse java混淆打包,Android Studio和eclipse混淆打包总结
- android 代码混淆
- 解决cannot resolve directory问题
- [HTML5]配置Ngnix服务器支持manifest
- 小实操(3): 利用键盘事件实现小人快跑
- JavaScript快速入门到高级 JS精品视频课程