After the last war devastated your country, you - as the king of the land of Ardenia - decided it was
high time to improve the defense of your capital city. A part of your fortication is a line of mage
towers, starting near the city and continuing to the northern woods. Your advisors determined that the
quality of the defense depended only on one factor: the length of a longest contiguous tower sequence
of increasing heights. (They gave you a lengthy explanation, but the only thing you understood was
that it had something to do with ring energy bolts at enemy forces).
After some hard negotiations, it appeared that building new towers is out of question. Mages of
Ardenia have agreed to demolish some of their towers, though. You may demolish arbitrary number of
towers, but the mages enforced one condition: these towers have to be consecutive.
For example, if the heights of towers were, respectively, 5, 3, 4, 9, 2, 8, 6, 7, 1, then by demolishing
towers of heights 9, 2, and 8, the longest increasing sequence of consecutive towers is 3, 4, 6, 7.
Input
The input contains several test cases. The rst line of the input contains a positive integer Z 25,
denoting the number of test cases. Then Z test cases follow, each conforming to the format described
below.
The input instance consists of two lines. The rst one contains one positive integer n 2 105
denoting the number of towers. The second line contains n positive integers not larger than 109
separated by single spaces being the heights of the towers.
Output
For each test case, your program has to write an output conforming to the format described below.
You should output one line containing the length of a longest increasing sequence of consecutive
towers, achievable by demolishing some consecutive towers or no tower at all.

 #include<cstdio>
#include<set>
#include<cstring>
#define M(a) memset(a,0,sizeof(a))
using namespace std;
struct ele
{
int a,g;
bool operator < (const ele & x) const
{
return a<x.a;
}
}e1,e2;
set<ele> s;
set<ele>::iterator it;
int a[],f[],g[];
int main()
{
int i,j,k,m,n,p,q,x,y,z,t,ans;
bool b;
scanf("%d",&t);
while (t--)
{
M(a);
M(f);
M(g);
s.clear();
scanf("%d",&n);
for (i=;i<=n;i++)
scanf("%d",&a[i]);
for (i=n;i>=;i--)
if (a[i]<a[i+]) f[i]=f[i+]+;
else f[i]=;
for (i=;i<=n;i++)
if (a[i]>a[i-]) g[i]=g[i-]+;
else g[i]=;
e1.a=a[];
e1.g=g[];
s.insert(e1);
ans=;
for (i=;i<=n;i++)
{
e1.a=a[i];
e1.g=g[i];
it=s.lower_bound(e1);
b=;
if (it!=s.begin())
{
e2=*(--it);
if (f[i]+e2.g>ans) ans=f[i]+e2.g;
if (e1.g<=e2.g) b=;
}
if (b)
{
s.erase(e1);
s.insert(e1);
it=s.find(e1);
it++;
while (it!=s.end()&&(*it).a>e1.a&&(*it).g<=e1.g) s.erase(it++);
}
}
printf("%d\n",ans);
}
}

因为不太会写stl,所以照着标程边抄边改边理解。

对于每个元素求出以它开头和结尾的最长递增子序列长度f[i]和g[i],那么对于每一个确定的后端点i,只需要找到满足a[j]<a[i]的最大g[j]即可。

易知如果a[j']>a[j]且g[j']<=g[j],则j’一定没用,因为j不但比他容易用,还比他效果好。

用set存储所有满足条件的pair<a[j],g[j]>,按a排序【则g也一定有序】。对于每个i,用lower_bound找到第一个>=它的,也就找到了最后一个<它的。用其更新答案。

用i更新完ans之后,需要把i也插入set中,为后面的元素服务。先判断i是否要插入(也就是有没有比他好的,只需要和刚才找见的最后一个<它的比较即可),再看插入之后可以删掉哪些元素(也就是没有它好的,向他前面一个一个找)。

uva 1471 defence lines——yhx的更多相关文章

  1. UVa 1471 Defense Lines - 线段树 - 离散化

    题意是说给一个序列,删掉其中一段连续的子序列(貌似可以为空),使得新的序列中最长的连续递增子序列最长. 网上似乎最多的做法是二分查找优化,然而不会,只会值域线段树和离散化... 先预处理出所有的点所能 ...

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

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

  3. uva 1471 Defense Lines

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

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

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

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

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

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

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

  7. Uva 1471 Defense Lines(LIS变形)

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

  8. UVa 1471 (LIS变形) Defense Lines

    题意: 给出一个序列,删掉它的一个连续子序列(该子序列可以为空),使得剩下的序列有最长的连续严格递增子序列. 分析: 这个可以看作lrj的<训练指南>P62中讲到的LIS的O(nlogn) ...

  9. 【uva 1471】Defense Lines(算法效率--使用数据结构+部分枚举+类贪心)

    P.S.我完全一个字一个字敲出来的血泪史啊~~所以,没有附代码,也是可以理解的啦.OvO 题意:给一个长度为N(N≤200000)的序列,要删除一个连续子序列,使得剩下的序列中有一个长度最大的连续递增 ...

随机推荐

  1. 不可或缺 Windows Native (3) - C 语言: 运算符,表达式,条件语句,循环语句,转向语句,空语句等

    [源码下载] 不可或缺 Windows Native (3) - C 语言: 运算符,表达式,条件语句,循环语句,转向语句,空语句等 作者:webabcd 介绍不可或缺 Windows Native  ...

  2. javascript indexOf startWith

    判断字符串是否以XX开头 1.切割转换   var str = "ababaa",tags = jquery.trim(str); 2. indexOf方法运行   !tags.i ...

  3. [js开源组件开发]-手机端照片预览组件

    手机端照片预览组件 可怜的我用着华为3C手机,用别人现成的组件都好卡,为了适应我这种屌丝,于是自己简化写了一版的照片预览效果,暂时无缩放功能,以后可能有空再加吧,你也可以自己加下,这是个github上 ...

  4. 约瑟夫问题(c++实现)

    描述:约瑟夫问题:有n只猴子,按顺时针方向围成一圈选大王(编号从1到n),从第1号开始报数,一直数到m,数到m的猴子退出圈外,剩下的猴子再接着从1 开始报数.就这样,直到圈内只剩下一只猴子时,这个猴子 ...

  5. YUIDoc example代码高亮错误、生成API文档目录不按源文件注释顺序

    1.如果发现yuidoc命令用不了,那就重装nodejs吧 昨天不知道是清扫电脑的原因,yuidoc命令用不了(命令不存在),也没有找到好的解决方法,怒重装YUIDoc也不行.最后想了想,怒重装了no ...

  6. 关于js中两种定时器的设置及清除

    1.JS中的定时器有两种: window.setTimeout([function],[interval]) 设置一个定时器,并且设定了一个等待的时间[interval],当到达时间后,执行对应的方法 ...

  7. ABAP内表(internal table)有关的系统变量

    SY-TABIX – 内表当前行的索引号.SY-TABIX 的值可以被以下命令修改,但是只适用于索引表(index table).对于哈希表(Hashed table),这个系统变量的值为空或0. A ...

  8. swift 字符转为类,代码创建控件

    在使用类之前要先获得 命名空间 通过json来获取 字符型的类名 然后创建类对象,这时候就要用到字符转类 // 从info字典中获取到 命名空间 转为字符型 let NS = NSBundle.mai ...

  9. Mac OS X上安装 Ruby运行环境

    环境   对于新入门的开发者,如何安装 Ruby和Ruby Gems 的运行环境可能会是个问题,本页主要介绍如何用一条靠谱的路子快速安装 Ruby 开发环境.此安装方法同样适用于产品环境! 系统需求 ...

  10. iOS label根据显示内容自适应大小

    - (void)setupLabel { //准备工作 UILabel *textLabel = [[UILabel alloc] init]; textLabel.font = [UIFont sy ...