UVa 1471 Defense Lines (二分+set优化)
题意:给定一个序列,然后让你删除一段连续的序列,使得剩下的序列中连续递增子序列最长。
析:如果暴力枚举那么时间复杂度肯定受不了,我们可以先进行预处理,f[i] 表示以 i 结尾的连续最长序列,g[i] 表示以 i 开头的连续最长序列,然后再去找最长的,
枚举 i,然后用set来维护一个单调上升的序列,我们把已经扫过的用set处理,按a[i]从小到大排序,然后f[i]也是从小到大,把不是最优的解全删掉,从而减少的要遍历的数目。
然后动态处理每个值。
代码如下:
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
#define debug puts("+++++")
//#include <tr1/unordered_map>
#define freopenr freopen("in.txt", "r", stdin)
#define freopenw freopen("out.txt", "w", stdout)
using namespace std;
//using namespace std :: tr1; typedef long long LL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const double inf = 0x3f3f3f3f3f3f;
const LL LNF = 0x3f3f3f3f3f3f;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 2e5 + 5;
const LL mod = 1e3 + 7;
const int N = 1e6 + 5;
const int dr[] = {-1, 0, 1, 0, 1, 1, -1, -1};
const int dc[] = {0, 1, 0, -1, 1, -1, 1, -1};
const char *Hex[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
inline LL gcd(LL a, LL b){ return b == 0 ? a : gcd(b, a%b); }
inline int gcd(int a, int b){ return b == 0 ? a : gcd(b, a%b); }
inline int lcm(int a, int b){ return a * b / gcd(a, b); }
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline int Min(int a, int b){ return a < b ? a : b; }
inline int Max(int a, int b){ return a > b ? a : b; }
inline LL Min(LL a, LL b){ return a < b ? a : b; }
inline LL Max(LL a, LL b){ return a > b ? a : b; }
inline bool is_in(int r, int c){
return r >= 0 && r < n && c >= 0 && c < m;
}
int a[maxn];
int g[maxn], f[maxn];
struct Node{
int id, num;
Node(int i, int n) : id(i), num(n) { }
bool operator < (const Node &p) const{
return id < p.id;
}
};
set<Node> sets;
set<Node> :: iterator it; int main(){
int T; cin >> T;
while(T--){
sets.clear();
scanf("%d", &n);
for(int i = 0; i < n; ++i) scanf("%d", a+i);
f[0] = 1;
for(int i = 1; i < n; ++i)
if(a[i] > a[i-1]) f[i] = f[i-1] + 1;
else f[i] = 1;
g[n-1] = 1;
for(int i = n-2; i >= 0; --i)
if(a[i] < a[i+1]) g[i] = g[i+1] + 1;
else g[i] = 1;
int ans = f[0] + g[0] - 1;
sets.insert(Node(a[0], 1));
for(int i = 1; i < n; ++i){
Node u(a[i], f[i]);
it = sets.lower_bound(u);
bool ok = true;
if(it != sets.begin()){
--it;
ans = Max(ans, g[i] + it->num);
if(it->num >= f[i]) ok = false;
}
if(ok){
sets.erase(u);
while(it != sets.end() && it->id > a[i] && it->num <= f[i]) sets.erase(it++);
sets.insert(u);
}
}
printf("%d\n", ans);
}
return 0;
}
UVa 1471 Defense Lines (二分+set优化)的更多相关文章
- UVA - 1471 Defense Lines 树状数组/二分
Defense Lines After the last war devastated your country, you - as the ...
- UVa 1471 Defense Lines - 线段树 - 离散化
题意是说给一个序列,删掉其中一段连续的子序列(貌似可以为空),使得新的序列中最长的连续递增子序列最长. 网上似乎最多的做法是二分查找优化,然而不会,只会值域线段树和离散化... 先预处理出所有的点所能 ...
- UVA - 1471 Defense Lines (set/bit/lis)
紫薯例题+1. 题意:给你一个长度为n(n<=200000)的序列a[n],求删除一个连续子序列后的可能的最长连续上升子序列的长度. 首先对序列进行分段,每一段连续的子序列的元素递增,设L[i] ...
- UVA 1471 Defense Lines 防线 (LIS变形)
给一个长度为n的序列,要求删除一个连续子序列,使剩下的序列有一个长度最大的连续递增子序列. 最简单的想法是枚举起点j和终点i,然后数一数,分别向前或向后能延伸的最长长度,记为g(i)和f(i).可以先 ...
- Uva 1471 Defense Lines(LIS变形)
题意: 给你一个数组,让你删除一个连续的子序列,使得剩下的序列中有最长上升子序列, 求出这个长度. 题解: 预处理:先求一个last[i],以a[i]为开始的合法最长上升子序列的长度.再求一个pre[ ...
- uva 1471 Defense Lines
题意: 给一个长度为n(n <= 200000) 的序列,你删除一段连续的子序列,使得剩下的序列拼接起来,有一个最长的连续递增子序列 分析: 就是最长上升子序列的变形.需要加一个类似二分搜索就好 ...
- uva 1471 defence lines——yhx
After the last war devastated your country, you - as the king of the land of Ardenia - decided it wa ...
- 1471 - Defense Lines
After the last war devastated your country, you - as the king of the land of Ardenia - decided it wa ...
- 【二分】Defense Lines
[UVa1471] Defense Lines 算法入门经典第8章8-8 (P242) 题目大意:将一个序列删去一个连续子序列,问最长的严格上升子序列 (N<=200000) 试题分析:算法1: ...
随机推荐
- 【2018 Multi-University Training Contest 1】
01:https://www.cnblogs.com/myx12345/p/9362221.html 02:https://www.cnblogs.com/myx12345/p/9382267.htm ...
- CPM、CPC、CPA、PFP、CPS、CPL、CPR介绍
一个网络媒体(网站)会包含有数十个甚至成千上万个页面,网络广告所投放的位置和价格 就牵涉到特定的页面以及浏览人数的多寡.这好比平面媒体(如报纸)的“版位”.“发行 量”,或者电波媒体(如电视)的“时段 ...
- XCode 或者ITune 添加账号时,提示:This action could not be completed. 或者 Access Privileges
当遇到This action could not be completed 或者 You do not have enough access privileges for this operation ...
- oc温习三:常用函数
参考文章: 算术函数 [算术函数] 函数名 说明 int rand() 随机数生成.(例)srand(time(nil)); //随机数初期化int val = rand()P; //0-49之间的随 ...
- 第18章:MYSQL分区
第18章:分区 目录 18.1. MySQL中的分区概述 18.2. 分区类型 18.2.1. RANGE分区 18.2.2. LIST分区 18.2.3. HASH分区 18.2.4. KEY分区 ...
- UVAlive 3026 KMP 最小循环节
KMP算法: 一:next数组:next[i]就是前面长度为i的字符串前缀和后缀相等的最大长度,也即索引为i的字符失配时的前缀函数. 二:KMP模板 /* pku3461(Oulipo), hdu17 ...
- HDU 5668 Circle
中国剩余定理. 可以手动模拟一下每一次开始的人的编号和结束的人的编号. 每次删掉一个人,对剩下的人重新编号. 这样一次模拟下来,可以得到n个方程 形如:(u[i]+k)%(n-i+1)=v[i] 化简 ...
- 【Java源码】集合类-LinkedList
一.类继承关系 LinkedList和ArrayList都实现了List接口.所以有List的特性,同时LinkedList也实现了Deque,所以它也具有双端队列和栈的特性. public clas ...
- java 并发基础,及案例分析
对于我们开发的网站,如果网站的访问量非常大的话,那么我们就需要考虑相关的并发访问问题了,然而并发问题是令我们大多数程序员头疼的问题,但话又说回来了,既然逃避不掉,那我们就坦然面对吧~今天就让我们深入研 ...
- 从头认识Spring-3.1 简单的AOP日志实现-某方法之前的前后记录日志
这一章节我们引入简单的AOP日志实现. 1.domain 蛋糕类: package com.raylee.my_new_spring.my_new_spring.ch03.topic_1_1; pub ...