求最长连续上升子序列,wa了 好多次啊,因为一开始 query的时候没处理好,然后就越想越离谱了,后来直接以为是 最长上升子序列,各种讨论,n次wa之后终于再回想起来。
#include<iostream> #include<algorithm> using namespace std; #define lson u<<1 #define rson u<<1|1 #define MAXN 100010 #define Max(a,b,c) ((a)>(b)?(a)>(c)?(a):(c):(b)>(c)?(b):(c)) struct Node{ int lef,rig; int lsum,rsum,msum; int st,ed; }T[MAXN<<2]; void Build(int u,int l,int r){ T[u].lef=l; T[u].rig=r; T[u].st=T[u].ed=0; T[u].lsum=T[u].rsum=T[u].msum=0; if(l==r)return; int mid=(l+r)>>1; Build(lson,l,mid); Build(rson,mid+1,r); } void PushUp(int u){ int len=T[u].rig-T[u].lef+1; T[u].st=T[lson].st; T[u].ed=T[rson].ed; T[u].lsum=T[lson].lsum; T[u].rsum=T[rson].rsum; if(T[u].lsum==(len+1)>>1&&T[lson].ed<T[rson].st)T[u].lsum+=T[rson].lsum;//lsum扩展 if(T[u].rsum==len>>1&&T[lson].ed<T[rson].st)T[u].rsum+=T[lson].rsum;//rsum扩展 T[u].msum=max(T[lson].msum,T[rson].msum); if(T[lson].rsum+T[rson].lsum>T[u].msum&&T[lson].ed<T[rson].st) T[u].msum=T[lson].rsum+T[rson].lsum; } void Update(int u,int pos,int val){ if(T[u].lef==T[u].rig){ T[u].st=T[u].ed=val; T[u].lsum=T[u].rsum=T[u].msum=1; //return; } else { if(pos<=T[lson].rig)Update(lson,pos,val); else Update(rson,pos,val); PushUp(u); } } int Query(int u,int l,int r){ if(l==T[u].lef&&T[u].rig==r)return T[u].msum; else { if(r<=T[lson].rig)return Query(lson,l,r); if(l>=T[rson].lef)return Query(rson,l,r); else { if(T[lson].ed<T[rson].st){ int ret=min(T[lson].rig-l+1,T[lson].rsum)+min(T[rson].lsum,r-T[rson].lef+1);//这里注意lson的rsum可能扩展过,rson的lsum也是,所以要取小 return Max(ret,Query(lson,l,T[lson].rig),Query(rson,T[rson].lef,r)); } else return max(Query(lson,l,T[lson].rig),Query(rson,T[rson].lef,r)); } } } int main(){ int t; int n,m; scanf("%d",&t); while(t--){ int a,b; char cmd; scanf("%d%d",&n,&m); Build(1,1,n); for(int i=1;i<=n;i++){ scanf("%d",&b); Update(1,i,b); } while(m--){ scanf(" %c%d%d",&cmd,&a,&b); if(cmd=='U'){ Update(1,a+1,b); } else { int ans=Query(1,a+1,b+1); printf("%d\n",ans); } } } return 0; }