HDU 3308 LCIS
线段树区间合并
/* *********************************************** Author :Zhou Zhentao Email :774388357@qq.com Created Time :2015/11/28 9:05:25 File Name :main.cpp ************************************************ */ #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <math.h> #include <stdlib.h> #include <time.h> using namespace std; const int maxn=100000+10; struct SegTree { int lsum,rsum,msum; int lnum,rnum; }segTree[4*maxn]; int T,N,Q; void pushUp(int rt,int len) { //确定左边第一个数字 segTree[rt].lnum=segTree[2*rt].lnum; //确定右边第一个数字 segTree[rt].rnum=segTree[2*rt+1].rnum; //确定从左开始的最长连续上升的长度 if(segTree[2*rt].msum==len-len/2&&segTree[2*rt].rnum<segTree[2*rt+1].lnum) segTree[rt].lsum=segTree[2*rt].lsum+segTree[2*rt+1].lsum; else segTree[rt].lsum=segTree[2*rt].lsum; //确定从右开始的最长连续上升的长度 if(segTree[2*rt+1].msum==len/2&&segTree[2*rt].rnum<segTree[2*rt+1].lnum) segTree[rt].rsum=segTree[2*rt].rsum+segTree[2*rt+1].rsum; else segTree[rt].rsum=segTree[2*rt+1].rsum; //确定区间最长连续上升的长度 segTree[rt].msum=max(segTree[2*rt].msum,segTree[2*rt+1].msum); if(segTree[2*rt].rnum<segTree[2*rt+1].lnum) segTree[rt].msum=max(segTree[rt].msum,segTree[2*rt].rsum+segTree[2*rt+1].lsum); } void build(int l,int r,int rt) { if(l==r) { scanf("%d",&segTree[rt].lnum); segTree[rt].rnum=segTree[rt].lnum; segTree[rt].lsum=segTree[rt].rsum=segTree[rt].msum=1; return ; } int m=(l+r)/2; build(l,m,rt*2); build(m+1,r,rt*2+1); pushUp(rt,r-l+1); } void update(int p,int add,int l,int r,int rt) { if(l==r) { segTree[rt].lnum=add; segTree[rt].rnum=add; return; } int m=(l+r)/2; if(p<=m) update(p,add,l,m,2*rt); else update(p,add,m+1,r,2*rt+1); pushUp(rt,r-l+1); } int quary(int L,int R,int l,int r,int rt) { if(L<=l&&R>=r) { return segTree[rt].msum; } int m=(l+r)/2; if(R<=m) return quary(L,R,l,m,2*rt); else if(L>=m+1) return quary(L,R,m+1,r,2*rt+1); else { int Q1=quary(L,R,l,m,2*rt); int Q2=quary(L,R,m+1,r,2*rt+1); int ans=max(Q1,Q2); int Min1=min(segTree[2*rt].rsum,m-L+1); int Min2=min(segTree[2*rt+1].lsum,R-m); if(segTree[2*rt].rnum<segTree[2*rt+1].lnum) ans=max(ans,Min1+Min2); return ans; } } int main() { scanf("%d",&T); while(T--) { scanf("%d%d",&N,&Q); build(1,N,1); for(int i=1;i<=Q;i++) { char op[5]; int x,y; scanf("%s",op); if(op[0]=='Q') { scanf("%d%d",&x,&y); printf("%d\n", quary(x+1,y+1,1,N,1)); } else if(op[0]=='U') { scanf("%d%d",&x,&y); update(x+1,y,1,N,1); } } } return 0; }