hdu 3308(线段树)
Posted wangwanxiang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 3308(线段树)相关的知识,希望对你有一定的参考价值。
线段树求区间最长连续上升
#include <iostream> #include <cstring> #include <algorithm> #include <cstdio> using namespace std; const int maxn=1e5+100; int ll[maxn<<2],rr[maxn<<2];//左边的连续上升子序列长度和右边的连续上升子序列长度 int a[maxn]; int mx[maxn<<2];//最长连续上升子序列长度 int t,n,m; void pushup(int l,int r,int rt) { ll[rt]=ll[rt<<1]; rr[rt]=rr[rt<<1|1]; mx[rt]=max(mx[rt<<1],mx[rt<<1|1]); int mid=(l+r)>>1; if(a[mid]<a[mid+1]) { int zz=rr[rt<<1]+ll[rt<<1|1]; mx[rt]=max(mx[rt],zz); if(rr[rt<<1]==mid-l+1) ll[rt]=zz; if(ll[rt<<1|1]==r-mid) rr[rt]=zz; } } void build(int l,int r,int rt) { ll[rt]=1; rr[rt]=1; mx[rt]=1; if(l==r) { scanf("%d",&a[l]); ll[rt]=1; rr[rt]=1; mx[rt]=1; return; } int mid=(l+r)>>1; build(l,mid,rt<<1); build(mid+1,r,rt<<1|1); pushup(l,r,rt); } void upnode(int p,int vv,int l,int r,int rt) { if(l==r) { a[l]=vv; return; } int mid=(l+r)>>1; if(p<=mid) upnode(p,vv,l,mid,rt<<1); else if(p>mid) upnode(p,vv,mid+1,r,rt<<1|1); pushup(l,r,rt); } int query(int L,int R,int l,int r,int rt) { if(L<=l&&r<=R) return mx[rt]; int mid=(l+r)>>1; int maxi=0; if(L<=mid&&mid<R) { maxi=max(query(L,R,l,mid,rt<<1),query(L,R,mid+1,r,rt<<1|1)); if(a[mid]<a[mid+1]) { int lll=min(mid-L+1,rr[rt<<1]); int rrr=min(R-mid,ll[rt<<1|1]); maxi=max(maxi,lll+rrr); } } else if(L<=mid) maxi=query(L,R,l,mid,rt<<1); else if(R>mid) maxi=query(L,R,mid+1,r,rt<<1|1); return maxi; } int main() { scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); build(0,n-1,1); getchar(); getchar(); char cc; int x,y; for(int i=1;i<=m;i++) { scanf("%c",&cc); scanf("%d%d",&x,&y); getchar(); if(cc==‘U‘) { upnode(x,y,0,n-1,1); } else { int hh=query(x,y,0,n-1,1); printf("%d ",hh); } } } return 0; }
子序列,这里是直接将输入存一个数组,在数组里修改,而不是在树里修改,方便查询两个区间是否能构成连续上升序列
以上是关于hdu 3308(线段树)的主要内容,如果未能解决你的问题,请参考以下文章