【43.49%】【hdu3308】LCIS
来源:互联网 发布:网点纸淘宝 编辑:程序博客网 时间:2024/06/05 00:14
Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 6593 Accepted Submission(s): 2867
You have two operations:
U A B: replace the Ath number by B. (index counting from 0)
Q A B: output the length of the longest consecutive increasing subsequence (LCIS) in [a, b].
Each case starts with two integers n , m(0<n,m<=105).
The next line has n integers(0<=val<=105).
The next m lines each has an operation:
U A B(0<=A,n , 0<=B=105)
OR
Q A B(0<=A<=B< n).
110 107 7 3 3 5 9 9 8 1 8 Q 6 6U 3 4Q 0 1Q 0 5Q 4 7Q 3 5Q 0 2Q 4 6U 6 10Q 0 9
11423125
【题解】
题意。给你n个整数。
会有以下两种操作:
1.把某个整数替换成另外一个数。
2.求出[l,r]这个区间内的最长上升子序列的长度。
思路是。
把一个区间[l,r]分成左右两部分。
那么这个区间内的最长上升子序列分两种情况。
第一种。整个序列都在左边。
第二种。整个序列都在右边。
第三种。一部分序列在左边,一部分序列在右边。
基于第三种。我们要在做线段树的时候记录两个值。
llong[rt],rlong[rt]。
分别表示以(rt所代表的线段的)最左边和以(rt所代表的线段的)最右边为起点和终点的最长上升子序列的长度。
如果rt<<1所在区间的最右边的元素<编号为rt<<1|1的节点所代表的区间的最左边的元素。则这两部分可以串起来。
即rlong[rt<<1]+llong[rt<<1|1];
这个可以用来更新我们记录的第3个值maxlong[rt]
即rt这个区间内不管在哪里的最长上升子序列的长度。
更具体一点,maxlong[rt] = max(maxlong[rt<<1],maxlong[rt<<1|1]);
if (左儿子最右边<右儿子最左边)
maxlong[rt] = max(maxlong[rt],rlong[rt<<1]+llong[rt<<1|1]);
记录所有节点所代表的区间的最左边和最右边的元素就可以了。
询问的时候也用类似的办法。
【代码】
#include <cstdio>#include <algorithm>#define lson begin,m,rt<<1#define rson m+1,end,rt<<1|1using namespace std;const int MAXN = 100001;int n, m,llong[MAXN*4],rlong[MAXN*4],maxlong[MAXN*4],lnum[MAXN*4],rnum[MAXN*4];void push_up(int rt, int len){bool flag = rnum[rt << 1] < lnum[rt << 1 | 1];maxlong[rt] = max(maxlong[rt << 1], maxlong[rt << 1 | 1]);if (flag) //左右两边接起来的情况maxlong[rt] = max(maxlong[rt], rlong[rt << 1] + llong[rt << 1 | 1]);llong[rt] = llong[rt << 1];if (flag && llong[rt] == (len - (len >> 1)))//如果整个左儿子都是上升llong[rt] += llong[rt << 1 | 1];//就尝试加上右儿子的左半部分作为rt的llongrlong[rt] = rlong[rt << 1 | 1];if (flag && rlong[rt] == (len >> 1))rlong[rt] += rlong[rt << 1];lnum[rt] = lnum[rt << 1];rnum[rt] = rnum[rt << 1 | 1];}void build(int begin, int end, int rt){llong[rt] = rlong[rt] = maxlong[rt] = 0;if (begin == end){int x;llong[rt] = rlong[rt] = maxlong[rt] = 1;scanf("%d", &x);lnum[rt] = rnum[rt] = x;return;}int m = (begin + end) >> 1;build(lson);build(rson);push_up(rt,end-begin+1);}void input_data(){scanf("%d%d", &n, &m);build(1, n, 1);}void up_data(int pos, int num, int begin, int end, int rt){if (begin == end){lnum[rt] = rnum[rt] = num;//修改的时候只要改最左边和最右边的元素return;}int m = (begin + end) >> 1;if (pos <= m)up_data(pos, num, lson);elseup_data(pos, num, rson);push_up(rt,end-begin+1);}int query(int l, int r, int begin, int end, int rt){if (l <= begin && end <= r)return maxlong[rt];int m = (begin + end) >> 1;bool flag1 = false, flag2 = false; //用来判断是否能划分为两个区间。int dd = 0;if (l <= m){dd = max(dd, query(l, r, lson));flag1 = true;}if (m < r){dd = max(dd, query(l, r, rson));flag2 = true;}if (flag1 && flag2 && rnum[rt << 1] < lnum[rt << 1 | 1]){int temp = min(m - l + 1, rlong[rt << 1]);//如果这个节点不完全在所询问的区间内int temp1 = min(r - m, llong[rt << 1 | 1]);//那么直接连起来是会越界的。dd = max(dd, temp + temp1);}return dd;}void output_ans(){for (int i = 1; i <= m; i++){int x, y;char op[10];scanf("%s", op);if (op[0] == 'U'){scanf("%d%d", &x, &y); //我下标习惯从1开始x++;up_data(x, y,1, n, 1);}else{scanf("%d%d", &x, &y);x++; y++; printf("%d\n",query(x, y, 1, n, 1));}}}int main(){//freopen("F:\\rush.txt", "r", stdin);//freopen("F:\\rush_out.txt", "w", stdout);int t;scanf("%d", &t);while (t--) //在输入的时候要递增!!!!!!!!!!!{input_data();output_ans();}return 0;}
- 【43.49%】【hdu3308】LCIS
- HDU3308 LCIS
- HDU3308--LCIS
- hdu3308 LCIS
- HDU3308 LCIS
- hdu3308----LCIS
- hdu3308 LCIS
- hdu3308 LCIS
- HDU3308-LCIS
- HDU3308 LCIS
- hdu3308 LCIS 线段树 难题
- hdu3308 LCIS(简单线段树)
- hdu3308 LCIS(区间求和)
- HDU3308:LCIS(线段树区间合并)
- hdu3308 LCIS(线段树区间合并)
- hdu3308 LCIS 线段树 区间合并
- 线段树区间合并 hdu3308 LCIS
- HDU3308-LCIS-线段树区间合并
- leetcode之234. Palindrome Linked List(C++解法)
- 数据帧、数据包、数据报以及数据段
- Balanced Binary Tree
- AngularJS之表格
- 51Nod 1179
- 【43.49%】【hdu3308】LCIS
- 数据库SQL优化大总结之 百万级数据库优化方案
- 获取短信验证码并实现登录
- Unity下利用WinAPI打开FileDialog
- iOS 开发 Pch 文件的正确使用
- c++ 学习笔记之复合数据类型
- opencv中视频数据类型及视频帧的读取与存储
- Android 手机获取短信验证码—自带UI界面
- 贫穷与富有