对于线段树的合并,需要建立左右区间的ans,和整个区间的ans。
LCIS只需要更新就行,二hotel则要用到区间的更新和合并。
LCIS:
//#define zhouV #include<cstdio> #include<iostream> #include<algorithm> #include<map> #include<set> #include<vector> using namespace std; #define LL long long int const int maxn= 100000; struct ss { int l,r,lb,rb,c; int lcis,rcis,mcis; }T[4*maxn]; void Push_up(int id) { int temp=id<<1; T[id].lcis=T[temp].lcis; T[id].rcis=T[temp+1].rcis; T[id].lb=T[temp].lb; T[id].rb=T[temp+1].rb; T[id].mcis=max( T[temp].mcis,T[temp+1].mcis) ; if(T[temp].rb<T[temp+1].lb) { if(T[temp].c==T[temp].lcis) T[id].lcis+=T[temp+1].lcis; if(T[temp+1].rcis==T[temp+1].c) T[id].rcis+=T[temp].rcis; T[id].mcis=max(T[id].mcis,T[temp].rcis+T[temp+1].lcis) ; } } void build(int id,int l,int r) { T[id].l=l; T[id].r=r; T[id].c=r-l+1; if(l==r) { scanf("%d",&T[id].rb); T[id].lb=T[id].rb; T[id].lcis=T[id].mcis=T[id].rcis=1; return ; } int mid=(l+r)>>1; build(2*id,l,mid); build(2*id+1,mid+1,r); Push_up(id); } void inset(int id,int x,int v) { if(T[id].l==T[id].r) { T[id].lb=T[id].rb=v; return ; } int mid=(T[id].l+T[id].r)>>1; if(x<=mid) inset(2*id,x,v); else inset(2*id+1,x,v); Push_up(id); } int query(int id,int l,int r) { if(T[id].l>=l && T[id].r<=r) { return T[id].mcis; } int mid=(T[id].l+T[id].r)>>1; int ans=0; if(l<=mid) ans=max(ans,query(2*id,l,r)); if(r>mid) ans=max(ans,query(2*id+1,l,r)); if(T[2*id].rb<T[2*id+1].lb) { ans=max(ans,min(mid-l+1,T[2*id].rcis)+min(r-mid,T[2*id+1].lcis)); } return ans; } int main() { #ifdef zhouV freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); #endif int t; scanf("%d",&t); while(t--) { int n,m,a,b; char s[5]; scanf("%d%d",&n,&m); build(1,1,n); while(m--) { scanf("%s",s); scanf("%d%d",&a,&b); if(s[0]=='U') { inset(1,a+1,b); } else printf("%d\n",query(1,a+1,b+1)); } } }
hotel:
//#define zhouV #include<string.h> #include<stdio.h> #include<iostream> #include<algorithm> using namespace std; #define LL long long int const int maxn=50010; struct ss { int l,r; int covert,lans,rans,mans;; }T[4*maxn]; void push_up(int id) { T[id].lans=T[id<<1].lans; T[id].rans=T[id<<1|1].rans; T[id].mans=max(T[id].lans,T[id].rans); if(T[id<<1].lans==T[id<<1].r-T[id<<1].l+1) { T[id].lans+=T[id<<1|1].lans; } if(T[id<<1|1].rans==T[id<<1|1].r-T[id<<1|1].l+1) { T[id].rans+=T[id<<1].rans; } T[id].mans=max(T[id<<1].rans+T[id<<1|1].lans,max(T[id<<1].mans,T[id<<1|1].mans)); } void build(int id,int l,int r) { T[id].covert=-1; T[id].lans=T[id].mans=T[id].rans=r-l+1; T[id].l=l; T[id].r=r; if(l==r) { return; } int mid=(l+r)>>1; build(id<<1,l,mid); build(id<<1|1,mid+1,r); } void Push_down(int id) { if(T[id].covert!=-1) { T[id<<1].covert=T[id<<1|1].covert=T[id].covert; if(T[id].covert) { T[id<<1].mans =T[id<<1].rans=T[id<<1].lans=0; T[id<<1|1].mans =T[id<<1|1].rans=T[id<<1|1].lans=0; } else { T[id<<1].mans =T[id<<1].rans=T[id<<1].lans=T[id<<1].r-T[id<<1].l+1; T[id<<1|1].mans =T[id<<1|1].rans=T[id<<1|1].lans=T[id<<1|1].r-T[id<<1|1].l+1; } T[id].covert=-1; } } void Up_data(int id,int l,int r,int v) { if(T[id].l>=l&&T[id].r<=r) { T[id].covert=v; if(v==0) { T[id].lans=T[id].mans=T[id].rans=T[id].r-T[id].l+1; T[id].covert=v; } else { T[id].lans=0; T[id].rans=0; T[id].mans=0; } return ; } Push_down(id); int mid=( T[id].r+T[id].l)>>1; if(l<=mid) Up_data(2*id,l,r,v); if(r>mid) Up_data(2*id+1,l,r,v); push_up(id); } int query(int id,int n) { if(T[id].l==T[id].r) return T[id].l; Push_down(id); int mid=( T[id].r+T[id].l)>>1; if(T[id<<1].mans>=n) return query(id<<1, n); else if(T[id<<1].rans+T[id<<1|1].lans>=n) return mid-T[id<<1].rans+1; return query(2*id+1,n); } int main() { #ifdef zhouV freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); #endif int n,m; cin>>n>>m; build(1,1,n); while(m--) { int a,b,c,f; scanf("%d",&a); if(a==1) { scanf("%d",&b); if(T[1].mans<b) { printf("0\n"); continue; } else { f=query(1,b); printf("%d\n",f); Up_data(1,f,f+b-1,1); } } else { scanf("%d%d",&b,&c); Up_data(1,b,b+c-1,0); } } }