标签:题目 查询 algorithm else oid 合并 第一个 fine amp
题目链接:https://vjudge.net/problem/HDU-3308
解题思路:以len[ ]保存区间内的最长单调递增区间长度,以llen[ ]保存区间内从第一个元素开始的最长单调递增区间长度,以rlen[ ]保存区间内以最后一个元素为结尾的最长单调递增区间长度。【 b( ̄▽ ̄)d 好拗口啊~】
重点主要是在pushup()的区间合并操作和query( )的查询操作,都是在下精心策划出来的,希望看官能稍加体味,不吝赐教。
AC代码:
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 const int maxn=1e5+6; int llen[maxn<<2],rlen[maxn<<2],len[maxn<<2],tree[maxn]; void pushup(int l,int r,int rt){ int m=(l+r)>>1; llen[rt]=llen[rt<<1]; rlen[rt]=rlen[rt<<1|1]; if(tree[m+1]>tree[m]){ if(llen[rt<<1]==m-l+1) llen[rt]+=llen[rt<<1|1]; if(rlen[rt<<1|1]==r-m) rlen[rt]+=rlen[rt<<1]; len[rt]=max(max(len[rt<<1],len[rt<<1|1]),rlen[rt<<1]+llen[rt<<1|1]); } else len[rt]=max(len[rt<<1],len[rt<<1|1]); } void build(int l,int r,int rt){ if(l==r){ scanf("%d",&tree[l]); len[rt]=llen[rt]=rlen[rt]=1; return; } int m=(l+r)>>1; build(lson); build(rson); pushup(l,r,rt); } int query(int L,int R,int l,int r,int rt){ if(L<=l&&r<=R) return len[rt]; int m=(l+r)>>1; if(L<=m&&m<R){ int l1=query(L,R,lson),l2=query(L,R,rson); if(tree[m]<tree[m+1]){ int le=max(L,m-rlen[rt<<1]+1),ri=min(R,m+llen[rt<<1|1]); return max(max(l1,l2),ri-le+1); } return max(l1,l2); } else if(R<=m) return query(L,R,lson); else return query(L,R,rson); } void update(int d,int c,int l,int r,int rt){ if(d==l && d==r){ tree[d]=c; return; } int m=(l+r)>>1; if(m>=d) update(d,c,lson); else update(d,c,rson); pushup(l,r,rt); } int main(){ int T; scanf("%d\n",&T); while(T--){ int n,m; scanf("%d%d",&n,&m); build(0,n-1,1); while(m--){ char c[3]; int a,b; scanf("%s %d %d",c,&a,&b); if(c[0]==‘Q‘) printf("%d\n",query(a,b,0,n-1,1)); else update(a,b,0,n-1,1); } } return 0; }
标签:题目 查询 algorithm else oid 合并 第一个 fine amp
原文地址:http://www.cnblogs.com/Blogggggg/p/7190685.html