LCIS hdu3308 (线段树 区间合并)
作者:互联网
题意: 有两种操作 一种是单点改为b 一种是给出区间ab 区间ab的最大上升子序列个数。。
线段树目前学了三种 第一种单点操作很简单 第二种区域操作加上懒惰标记即可
现在这种 为区间合并。。。。多看就好了
#include<bits/stdc++.h> using namespace std; #define N 100010 #define lson L,m,pos<<1 #define rson m+1,R,pos<<1|1 #define mid m=(L+R)>>1 #define LL long long int lsum[N<<2],rsum[N<<2],ssum[N<<2],num[N]; void up(int L,int R,int pos) { int mid; lsum[pos]=lsum[pos<<1]; rsum[pos]=rsum[pos<<1|1]; ssum[pos]=max(ssum[pos<<1],ssum[pos<<1|1]);//向上 if(num[m]<num[m+1]) { if(lsum[pos]==(m-L+1))lsum[pos]+=lsum[pos<<1|1]; if(rsum[pos]==(R-m))rsum[pos]+=rsum[pos<<1]; ssum[pos]=max(ssum[pos],lsum[pos<<1|1]+rsum[pos<<1] ); } } void build(int L,int R,int pos) { if(L==R) { scanf("%d",&num[L]); lsum[pos]=rsum[pos]=ssum[pos]=1; return ; } int mid; build(lson); build(rson); up(L,R,pos); } void update(int x,int v,int L,int R,int pos) { if(L==R) { num[L]=v; return; } int mid; if(x<=m)update(x,v,lson); else update(x,v,rson); up(L,R,pos); } int query(int l,int r,int L,int R,int pos) { if(l<=L&&r>=R) return ssum[pos]; int mid; int ans=0; if(l<=m)ans=max(ans,query(l,r,lson)); if(r>m)ans=max(ans,query(l,r,rson)); if(num[m]<num[m+1]) ans=max(ans,min(m-l+1,rsum[pos<<1])+min(r-m,lsum[pos<<1|1] )); return ans; } int main() { char s[3]; int cas; scanf("%d",&cas); while(cas--) { int n,q; scanf("%d%d",&n,&q); build(1,n,1); while(q--) { int a,b; scanf("%s%d%d",s,&a,&b); if(s[0]=='Q') printf("%d\n",query(a+1,b+1,1,n,1)); else update(a+1,b,1,n,1); } } return 0; }
标签:LCIS,int,线段,pos,ab,hdu3308,ans,区间,define 来源: https://www.cnblogs.com/bxd123/p/10462422.html