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

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

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

Code

 /**
* UVa
* Problem#1471
* Accepted
* Time:1190ms
*/
#include<iostream>
#include<cstdio>
#include<cctype>
#include<ctime>
#include<cstring>
#include<cstdlib>
#include<fstream>
#include<sstream>
#include<algorithm>
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<vector>
#include<stack>
using namespace std;
typedef bool boolean;
#define inf 0xfffffff
#define smin(a, b) a = min(a, b)
#define smax(a, b) a = max(a, b)
template<typename T>
inline void readInteger(T& u){
char x;
int aFlag = ;
while(!isdigit((x = getchar())) && x != '-');
if(x == '-'){
x = getchar();
aFlag = -;
}
for(u = x - ''; isdigit((x = getchar())); u = (u << ) + (u << ) + x - '');
ungetc(x, stdin);
u *= aFlag;
} typedef class SegTreeNode {
public:
int val;
SegTreeNode *l, *r;
SegTreeNode(int val = , SegTreeNode* l = NULL, SegTreeNode* r = NULL):val(val), l(l), r(r) { } inline void pushUp() {
val = max(l->val, r->val);
}
}SegTreeNode; typedef class SegTree {
public:
SegTreeNode* root;
SegTree():root(NULL) { }
SegTree(int s) {
build(root, , s);
} void build(SegTreeNode*& node, int l, int r) {
node = new SegTreeNode();
if(l == r) return;
int mid = (l + r) >> ;
build(node->l, l, mid);
build(node->r, mid + , r);
} void update(SegTreeNode*& node, int l, int r, int idx, int val) {
if(l == idx && r == idx) {
smax(node->val, val);
return;
}
int mid = (l + r) >> ;
if(idx <= mid) update(node->l, l, mid, idx, val);
else update(node->r, mid + , r, idx, val);
node->pushUp();
} int query(SegTreeNode*& node, int l, int r, int ql, int qr) {
if(qr < ql) return -inf;
if(l == ql && r == qr) {
return node->val;
}
int mid = (l + r) >> ;
if(qr <= mid) return query(node->l, l, mid, ql, qr);
if(ql > mid) return query(node->r, mid - , r, ql, qr);
int sl = query(node->l, l, mid, ql, mid);
int sr = query(node->r, mid + , r, mid + , qr);
return max(sl, sr);
} inline void clear(SegTreeNode*& node) {
if(node == NULL) return;
clear(node->l);
clear(node->r);
delete[] node;
}
}SegTree; int T;
int n;
int len;
int* lis;
int* buf;
SegTree st; inline void init() {
readInteger(n);
lis = new int[(const int)(n + )];
buf = new int[(const int)(n + )];
for(int i = ; i <= n; i++)
readInteger(lis[i]);
} inline void descreate(int* a) {
memcpy(buf, a, sizeof(int) * (n + ));
sort(buf + , buf + n + );
len = unique(buf + , buf + n + ) - buf;
for(int i = ; i <= n; i++)
a[i] = lower_bound(buf + , buf + len, a[i]) - buf;
} int *tol, *tor;
inline void dp() {
tol = new int[(const int)(n + )];
tor = new int[(const int)(n + )];
tol[] = ;
for(int i = ; i <= n; i++)
tol[i] = (lis[i] > lis[i - ]) ? (tol[i - ] + ) : ();
tor[n] = ;
for(int i = n - ; i > ; i--)
tor[i] = (lis[i] < lis[i + ]) ? (tor[i + ] + ) : ();
} int result;
inline void solve() {
result = ;
descreate(lis);
st = SegTree(len);
dp();
// st.update(st.root, 1, len, lis[1], tol[1]);
for(int i = ; i <= n; i++) {
int c = st.query(st.root, , len, , lis[i] - );
smax(result, c + tor[i]);
st.update(st.root, , len, lis[i], tol[i]);
}
printf("%d\n", result);
delete[] tol;
delete[] tor;
delete[] buf;
delete[] lis;
st.clear(st.root);
} int main() {
readInteger(T);
while(T--) {
init();
solve();
}
return ;
}

UVa 1471 Defense Lines - 线段树 - 离散化的更多相关文章

  1. UVA - 1471 Defense Lines 树状数组/二分

                                  Defense Lines After the last war devastated your country, you - as the ...

  2. UVA - 1471 Defense Lines (set/bit/lis)

    紫薯例题+1. 题意:给你一个长度为n(n<=200000)的序列a[n],求删除一个连续子序列后的可能的最长连续上升子序列的长度. 首先对序列进行分段,每一段连续的子序列的元素递增,设L[i] ...

  3. uva 1471 Defense Lines

    题意: 给一个长度为n(n <= 200000) 的序列,你删除一段连续的子序列,使得剩下的序列拼接起来,有一个最长的连续递增子序列 分析: 就是最长上升子序列的变形.需要加一个类似二分搜索就好 ...

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

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

  5. UVa 1471 Defense Lines (二分+set优化)

    题意:给定一个序列,然后让你删除一段连续的序列,使得剩下的序列中连续递增子序列最长. 析:如果暴力枚举那么时间复杂度肯定受不了,我们可以先进行预处理,f[i] 表示以 i 结尾的连续最长序列,g[i] ...

  6. Uva 1471 Defense Lines(LIS变形)

    题意: 给你一个数组,让你删除一个连续的子序列,使得剩下的序列中有最长上升子序列, 求出这个长度. 题解: 预处理:先求一个last[i],以a[i]为开始的合法最长上升子序列的长度.再求一个pre[ ...

  7. HDU5124:lines(线段树+离散化)或(离散化思想)

    http://acm.hdu.edu.cn/showproblem.php?pid=5124 Problem Description John has several lines. The lines ...

  8. [poj2528] Mayor's posters (线段树+离散化)

    线段树 + 离散化 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayor ...

  9. D - Mayor's posters(线段树+离散化)

    题目: The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campai ...

随机推荐

  1. Gym - 101532D Counting Test 前缀和统计字符串

    题意:给你一个1e4长的字符串S,有1e5个询问,每个询问形如 l r c ,其中l,r为左右边界,c为所询问的字符.注意,l,r,可以大于串S的长度,这种情况下认为S自身重复无数次(S+S+S··· ...

  2. 懂点PS技巧,你会减少很多痛苦

    UI设计 不像平面设计那样随性, 期间可以用点技巧来减少痛苦. 1. 设置网格线 保持像素完美 不在1:1分辨率下也能保持像素完美,可以通过创建网格线来避免虚边的出现. 编辑 > 首选项 > ...

  3. vhost-user 分析1

    2018-01-24 占个坑,准备下写vhost-user的东西 vhost-user是vhost-kernel又回到用户空间的实现,其基本思想和vhost-kernel很类似,不过之前在内核的部分现 ...

  4. IO流(7)获取指定文件夹下的所有文件

    /* * 把E:\JavaSE目录下所有的java结尾的文件的绝对路径给输出在控制台. * * 分析: * A:封装目录 * B:获取该目录下所有的文件或者文件夹的File数组 * C:遍历该File ...

  5. CentOS工作内容(三)配置网络IP地址

    CentOS工作内容(三)配置网络IP地址 用到的快捷键 tab 自动补齐(有不知道的吗) ctrl+a 移动到当前行的开头(a ahead) ctrl+u 删除(剪切)此处至开始所有内容 vim 末 ...

  6. Inception系列

    从GoogLeNet的Inceptionv1开始,发展了众多inception,如inception v2.v3.v4与Inception-ResNet-V2. 故事还是要从inception v1开 ...

  7. c/c++ 中的char* ,const char* 和 char* const 总结[转]

    文章转自:c/c++ 中的char* ,const char* 和 char* const 总结 例1: char* str="abc";//错误写法 (在.c文件中是正确的) c ...

  8. idea 连接数据库

    1:如果没有数据库连接插件,下载database插件 settings>plugin>Database Navigator 下载. 2:重启 3:进入 view>tool windo ...

  9. iOS9 & iOS10 & iOS11 HTTP 不能正常使用的解决办法

    iOS9 & iOS10 & iOS11 HTTP 不能正常使用的解决办法 xcode  ios 291.4k 次阅读  ·  读完需要 8 分钟 54 今天升级Xcode 7.0 b ...

  10. js随机点名系统

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...