CDOJ 360:Another LCIS(区间更新+区间合并)
来源:互联网 发布:mac os 终端命令 编辑:程序博客网 时间:2024/06/15 10:34
题目链接:http://acm.uestc.edu.cn/#/problem/show/360
题目翻译:给出N个数字,Q个操作,如果输入操作类型是a,则【L,R】区间中的数字都要加上V。
否则就查询【L,R】区间内最长连续递增子序列的长度。一个区间,其两个子区间依据边界值对
两个区间进行合并。
Max数组维护任意一个区间的最长连续子序列长度。
lnum数组保存一个区间左边界的数值
rnum数组保存一个区间右边界的数值
lsum数组保存以当前区间左边界为开始的最长连续递增子序列的长度
rsum数组保存以当前区间右边界为开始的最长连续递增子序列的长度。
每次用子区间去更新父区间。
父区间左边界值是它左子区间左边界值
父区间右边界值是它右子区间右边界值
父区间的lsum和rsum我们先继承其左右孩子的。
如果不考虑左右孩子区间的拼接,父区间中最长连续递增子序列的长度应该是其子区间中的最大值。
如果发现父区间的左区间的右边界值小于父区间的右区间的左边界值,则两个区间可以拼接。
如果左区间整断连续递增,则才可以与右区间以左边界为开始的最长连续递增子序列拼接,成为父区间
以左边界开始的最长连续子序列长度。如果右区间整断连续递增,则才可以与左区间以右边界为结束的最长
连续递增子序列进行拼接。
然后拼接左区间以右边界为结束的最长连续递增序列和右区间以左边界为开始的最长连续递增序列。
最后查询的时候需要注意,因为我们是查到子区间就返回答案,所以子区间中连续字符串的位置不一定
就在边界,所以我们需要处理一下。
#include <iostream>#include <stdio.h>#include <string.h>#include <algorithm>#define lchild left,mid,root<<1#define rchild mid+1,right,root<<1|1using namespace std;const int maxn = 100010;int lsum[maxn<<2],rsum[maxn<<2],Max[maxn<<2],lazy[maxn<<2];long long lnum[maxn<<2],rnum[maxn<<2];///更新当前节点的值void push_up(int left,int right,int root) { lnum[root] = lnum[root<<1]; ///区间的左边界是其左区间的左边界 rnum[root] = rnum[root<<1|1]; ///区间的有边界是其右区间的右边界 lsum[root] = lsum[root<<1]; ///以左端点为开始的连续递增序列长度是其左区间以左边界开始的连续递增序列长度 rsum[root] = rsum[root<<1|1]; ///以右断电为结束的连续递增序列长度是其右区间以有边界结束的连续递增序列长度 Max[root] = max(Max[root<<1],Max[root<<1|1]); long long leftright = rnum[root<<1]; ///左区间的右侧数字 long long rightleft = lnum[root<<1|1]; ///右区间的左侧数字 int mid = (left+right)>>1; ///两个区间可能拼接在一起。 if(leftright<rightleft) { if(lsum[root] == mid-left+1) { lsum[root] += lsum[root<<1|1]; } if(rsum[root] == right-mid) { rsum[root] += rsum[root<<1]; } Max[root] = max(Max[root],rsum[root<<1]+lsum[root<<1|1]); }}void push_down(int root) { if(lazy[root]) { lazy[root<<1] += lazy[root]; lazy[root<<1|1] += lazy[root]; lnum[root<<1] += lazy[root]; rnum[root<<1] += lazy[root]; lnum[root<<1|1] += lazy[root]; rnum[root<<1|1] += lazy[root]; lazy[root] = 0; }}void build(int left,int right,int root) { lazy[root] = 0; if(left == right) { scanf("%lld",&lnum[root]); rnum[root] = lnum[root]; Max[root] = lsum[root] = rsum[root] = 1; return; } int mid = (left+right)>>1; build(lchild); build(rchild); push_up(left,right,root);}void update(int L,int R,int add,int left,int right,int root) { if(L<=left && right<=R) { lnum[root] += add; rnum[root] += add; lazy[root] += add; return; } push_down(root); int mid = (left+right)>>1; if(L<=mid) update(L,R,add,lchild); if(R>mid) update(L,R,add,rchild); push_up(left,right,root);}int query(int L,int R,int left,int right,int root) { if(L<=left && right<=R) { return Max[root]; } push_down(root); int ans = 1; int mid = (left+right)>>1; if(L<=mid) ans = max(ans,query(L,R,lchild)); if(R>mid) ans = max(ans,query(L,R,rchild)); if(rnum[root<<1] < lnum[root<<1|1]) { ans = max(ans,min(R,mid+lsum[root<<1|1])-max(L,mid-rsum[root<<1]+1)+1); } return ans;}int main() { int T,Case=0; scanf("%d",&T); ///T组测试数据 while(T--) { int N,Q; scanf("%d%d",&N,&Q); ///N个数字,Q次操作 build(1,N,1); char op; int L,R,V; printf("Case #%d:\n",++Case); while(Q--) { scanf(" %c",&op); if(op == 'a') { scanf("%d%d%d",&L,&R,&V); update(L,R,V,1,N,1); } else { scanf("%d%d",&L,&R); int ans = query(L,R,1,N,1); printf("%d\n",ans); } } } return 0;}
阅读全文
0 0
- CDOJ 360:Another LCIS(区间更新+区间合并)
- uestc Another LCIS(区间更新,区间合并)
- UESTC 360 Another LCIS(线段树区间更新)
- UESTC 360 Another LCIS(线段树 x 经典区间合并姿势)
- hdu 3308 LCIS(单点更新,区间合并)
- hdu 3308 LCIS (线段树+单点更新+区间合并)
- HDU 3308 LCIS(线段树区间合并 单点更新)
- HDU 3308 LCIS(区间合并 + 单点更新)
- hdu 3308 LCIS(单点更新+区间合并)
- HDU 3308 LCIS (端点更新+区间合并)
- [UESTC]Another LCIS[线段树][区间合并][成段修改]
- hdu 3308 LCIS(区间合并)
- HDU3308 LCIS(线段树区间合并)
- hdu.3308 LCIS(线段树,区间合并+单点更新)
- HDU 3308 LCIS 线段树的单点更新,区间合并
- LCIS --线段树区间合并
- hdu 3308 LCIS(区间合并)
- hdu 3308 LCIS (区间合并)
- C的时间函数
- handler线程,判断是否联网,Get获取网页 json解析,输入流转换字符串
- 图解css3核心技术与案例实战(第一章)
- 7.读书笔记收获不止Oracle之 逻辑体系二 深入与调整
- Ubuntu 16.04下安装sogou 拼音输入法的错误问题
- CDOJ 360:Another LCIS(区间更新+区间合并)
- LeetCode 155: Min Stack
- matlab矩阵操作
- 如何从现有版本升级到element UI2.0
- [2017纪中11-2]失格 最小生成树+数论
- ASP.NET 事务处理
- hello
- 判断是否有网,判断网络连接,跳转至设置
- Linux命令(1)-cat & 反向tac