求给定不下降序列区间出现元素次数最多的次数。
节点信息:区间最左侧元素,最右侧元素,最左侧元素连续出现次数,最右侧元素连续次数,整个区间最多出现的次数。
因为是不下降序列,所以如果出现多次,必然是相邻元素。
然后线段树从节点往父节点合并更新即可。
#include <queue> #include <stack> #include <math.h> #include <stdio.h> #include <stdlib.h> #include <iostream> #include <limits.h> #include <string.h> #include <string> #include <algorithm> #define MID(x,y) ( ( x + y ) >> 1 ) #define L(x) ( x << 1 ) #define R(x) ( x << 1 | 1 ) #define BUG puts("here!!!") using namespace std; const int MAX = 100010; struct Tnode{ int l,r,ls,rs,lval,rval,sum; int getlen() { return r - l; } }; Tnode node[MAX<<2]; int a[MAX]; void init() { memset(node,0,sizeof(node)); } void Updata_sum(int t) { node[t].ls = node[L(t)].ls + ( node[L(t)].ls == node[L(t)].getlen() && node[L(t)].rval == node[R(t)].lval ? node[R(t)].ls : 0 ); node[t].rs = node[R(t)].rs + ( node[R(t)].rs == node[R(t)].getlen() && node[R(t)].lval == node[L(t)].rval ? node[L(t)].rs : 0 ); node[t].sum = max(node[L(t)].sum,node[R(t)].sum); if( node[L(t)].rval == node[R(t)].lval ) node[t].sum = max(node[t].sum,node[L(t)].rs+node[R(t)].ls); node[t].lval = node[L(t)].lval; node[t].rval = node[R(t)].rval; } void Build(int t,int l,int r) { node[t].l = l; node[t].r = r; if( node[t].l == node[t].r - 1 ) { node[t].ls = node[t].rs = node[t].sum = 1; node[t].lval = node[t].rval = a[l]; return ; } int mid = MID(l,r); Build(L(t),l,mid); Build(R(t),mid,r); Updata_sum(t); } int Query(int t,int l,int r) { if( node[t].l >= l && node[t].r <= r ) return node[t].sum; if( node[t].l == node[t].r - 1 ) return 0; int mid = MID(node[t].r,node[t].l); int ans = 0; if( l >= mid ) ans = max(ans,Query(R(t),l,r)); else if( r < mid ) ans = max(ans,Query(L(t),l,r)); else { ans = max(ans,Query(L(t),l,mid)); ans = max(ans,Query(R(t),mid,r)); if( node[L(t)].rval == node[R(t)].lval ) { int a = mid - l >= node[L(t)].rs ? node[L(t)].rs : mid - l; int b = r - mid >= node[R(t)].ls ? node[R(t)].ls : r - mid; ans = max(a+b,ans); } } return ans; } int main() { int n,m,x,y; while( ~scanf("%d",&n) && n ) { scanf("%d",&m); for(int i=0; i<n; i++) scanf("%d",&a[i]); init(); Build(1,0,n); while( m-- ) { scanf("%d%d",&x,&y); int ans = Query(1,x-1,y); printf("%d\n",ans); } } return 0; }