bzoj4491奇技淫巧线段树
20行的归并+10行的线段树(现在线段树真是越写越短了)+10行主程序(连主程序都缩过行) = =丧心病狂
struct里连开10个,用大括号直接初始化真是爽翻了
1 #include <cstdio> 2 #define mid ((l+r)>>1) 3 struct node 4 { 5 int ls,lj,rs,rj,s,ss,j,js,l,r; 6 } tr[500000],ans; 7 int a[50001]; 8 int n,m,p,q; 9 inline int max(int p,int q){return(p>q)?p:q;} 10 node merge(node p,node q) 11 { 12 node ans; 13 ans.l=p.l;ans.r=q.r; 14 ans.ls=p.ls;ans.lj=p.lj; 15 ans.rs=q.rs;ans.rj=q.rj; 16 17 if(p.s>q.s) ans.s=p.s,ans.ss=p.ss; 18 else ans.s=q.s,ans.ss=q.ss; 19 if(a[p.r]<=a[q.l]) 20 if(ans.s<p.rs+q.ls) 21 ans.s=p.rs+q.ls,ans.ss=p.r-p.rs+1; 22 if(ans.ss==p.l) ans.ls=ans.s; 23 if(ans.ss+ans.s-1==q.r) ans.rs=ans.s; 24 25 if(p.j>q.j) ans.j=p.j,ans.js=p.js; 26 else ans.j=q.j,ans.js=q.js; 27 if(a[p.r]>=a[q.l]) 28 if(ans.j<p.rj+q.lj) 29 ans.j=p.rj+q.lj,ans.js=p.r-p.rj+1; 30 if(ans.js==p.l) ans.lj=ans.j; 31 if(ans.js+ans.j-1==q.r) ans.rj=ans.j; 32 return ans; 33 } 34 void build(int now,int l,int r) 35 { 36 if(l!=r) 37 build(now<<1,l,mid),build(now<<1|1,mid+1,r),tr[now]=merge(tr[now<<1],tr[now<<1|1]); 38 else 39 tr[now]={1,1,1,1,1,l,1,l,l,l}; 40 } 41 node que(int now,int l,int r,int p,int q) 42 { 43 if(l==p && r==q) return tr[now]; 44 if(q<=mid) return que(now<<1,l,mid,p,q); 45 else if(p>mid) return que(now<<1|1,mid+1,r,p,q); 46 else return merge(que(now<<1,l,mid,p,mid),que(now<<1|1,mid+1,r,mid+1,q)); 47 } 48 int main() 49 { 50 for(scanf("%d",&n),p=1;p<=n;p++) 51 scanf("%d",&a[p]); 52 build(1,1,n); 53 for(scanf("%d",&m);m;m--) 54 scanf("%d%d",&p,&q),ans=que(1,1,n,p,q),printf("%d\n",max(ans.s,ans.j)); 55 return 0; 56 }
事实上应该是1A的,但是输出的时候没回车(mdzz)错了一发