首页 > 代码库 > hdu3308 线段树 求最大连续递增序列
hdu3308 线段树 求最大连续递增序列
对每个节点 left表示该节点前缀最大连续上升 right为后缀最大连续上升
all为整个区间最大连续上升 pre为区间左边值 after为右边值 其他和别的线段树都差不多 关键是看如何合并
#include<stdio.h> #include<string.h> #include<iostream> using namespace std; #define LL(x) (x<<1) #define RR(x) ((x<<1)|1) struct node { int left; int right; int all; int pre,after; }num[4*100000]; int max(int a,int b) { return a>b?a:b; } int min(int a,int b) { return a<b?a:b; } int update(int L,int R,int pos,int k,int mark) { if(L==R&&L==pos) { num[mark].left=1; num[mark].right=1; num[mark].all=1; num[mark].pre=num[mark].after=k; return 0; } int mid=(L+R)/2; if(pos<=mid) { update(L,mid,pos,k,LL(mark)); } else update(mid+1,R,pos,k,RR(mark)); num[mark].left=num[LL(mark)].left; if(num[LL(mark)].left==mid-L+1&&num[LL(mark)].after<num[RR(mark)].pre) num[mark].left+=num[RR(mark)].left; num[mark].right=num[RR(mark)].right; if(num[RR(mark)].right==R-mid&&num[RR(mark)].pre>num[LL(mark)].after) num[mark].right+=num[LL(mark)].right; num[mark].all=max(num[LL(mark)].all,num[RR(mark)].all); if(num[LL(mark)].after<num[RR(mark)].pre) num[mark].all=max(num[mark].all,num[LL(mark)].right+num[RR(mark)].left); num[mark].pre=num[LL(mark)].pre; num[mark].after=num[RR(mark)].after; return 0; } int find(int L,int R,int left,int right,int mark) { if(L==left&&R==right) { return num[mark].all; } int mid=(R+L)/2; if(right<=mid) return find(L,mid,left,right,LL(mark)); else if(left>mid) return find(mid+1,R,left,right,RR(mark)); else { int t1=find(L,mid,left,mid,LL(mark)); int t2=find(mid+1,R,mid+1,right,RR(mark)); int k=0; if(num[LL(mark)].after<num[RR(mark)].pre) k=min(num[LL(mark)].right,t1)+min(num[RR(mark)].left,t2); //k=t1+t2; return max(max(t1,t2),k); } } int main() { int n,m,i,j,a,T,b,c; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); n-=1; for(i=0;i<=n;i++) { scanf("%d",&a); //printf("%d%d%d\n",n,i,a); update(0,n,i,a,1); } char str[2]; //printf("%d\n",num[1].all); for(i=1;i<=m;i++) { scanf("%s%d%d",str,&b,&c); if(str[0]==‘Q‘) { //printf("%d%d\n",b,c); printf("%d\n",find(0,n,b,c,1)); } else { //printf("%d\n",n); update(0,n,b,c,1); } } } return 0; }
hdu3308 线段树 求最大连续递增序列
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。