pku3368 Frequent values

思路:在线段树的结点内设5个变量l、r、mx、lf、rf,[l,r]表示该结点的区间范围,lf和rf分别表示元素a[l]和a[r]在区间内的出现频率,mx表示区间内的最高出现频率。
假设区间[x,y]和[y+1,z]均被询问[i,j]覆盖,则可以分情况讨论区间[x,z]的mx值:
若a[y]==a[y+1],则mx[x,y]=max{mx[x,y],mx[y+1,z],rf[x,y]+lf[y+1,z]}
否则mx[x,y]=max{mx[x,y],mx[y+1,z]}

 

 

#include  < iostream >
using   namespace  std;

#define  clr(x) memset(x,0,sizeof(x))
#define  max(a,b) (a>b?a:b)
#define  min(a,b) (a<b?a:b)
#define  MAXN 100002

int  a[MAXN],n,q;

struct  Node{
    
int  lf,rf,l,r,mx;
};


Node nod[MAXN
* 3 ];

void  init( int  tag, int  left, int  right){
    
int  temp,sum;
    
if (left == right){
        nod[tag].l
= nod[tag].r = left;
        nod[tag].lf
= nod[tag].rf = 1 ;
        nod[tag].mx
= 1 ;
        
return ;
    }
    nod[tag].l
= left;
    nod[tag].r
= right;
    init(tag
* 2 ,left,(left + right) / 2 );
    init(tag
* 2 + 1 ,(left + right) / 2 + 1 ,right);

    nod[tag].rf
= nod[tag * 2 + 1 ].rf;
    nod[tag].lf
= nod[tag * 2 ].lf;

    temp
= nod[tag * 2 ].mx;
    
if (nod[tag * 2 + 1 ].mx > temp)
        temp
= nod[tag * 2 + 1 ].mx;    
    
if (a[nod[tag * 2 ].r] == a[nod[tag * 2 + 1 ].l]){
        sum
= nod[tag * 2 ].rf + nod[tag * 2 + 1 ].lf;
        
if (sum > temp)
            temp
= sum;
        
if (a[nod[tag].r] == a[nod[tag * 2 + 1 ].l])
            nod[tag].rf
= sum;
        
if (a[nod[tag].l] == a[nod[tag * 2 ].r])
            nod[tag].lf
= sum;
    }

    nod[tag].mx
= temp;
}

int  query( int  tag, int  left, int  right){
    
int  temp,q1,q2,sum;
    
if (left == nod[tag].l  &&  right == nod[tag].r){
        
return  nod[tag].mx;
    }

    
if (right <= nod[ 2 * tag].r)
        
return  query(tag * 2 ,left,right);
    
else   if (left >= nod[ 2 * tag + 1 ].l)
        
return  query(tag * 2 + 1 ,left,right);
    
else {
        q1
= query(tag * 2 ,left,nod[tag * 2 ].r);
        q2
= query(tag * 2 + 1 ,nod[tag * 2 + 1 ].l,right);
        temp
= q1;
        
if (q2 > temp)
            temp
= q2;
        
if (a[nod[tag * 2 ].r] == a[nod[tag * 2 + 1 ].l]){
            sum
= min(nod[tag * 2 ].r - left + 1 ,nod[tag * 2 ].rf) + min(right - nod[tag * 2 + 1 ].l + 1 ,nod[tag * 2 + 1 ].lf);
            
if (sum > temp)
                temp
= sum;
        }
        
return  temp;
    }
}



int  main(){
    
int  i,x,y;
    
while (scanf( " %d " , & n)  &&  n){
        scanf(
" %d " , & q);
        
for (i = 1 ;i <= n;i ++ )
            scanf(
" %d " , & a[i]);
        init(
1 , 1 ,n);
        
for (i = 0 ;i < q;i ++ ){
            scanf(
" %d%d " , & x, & y);
            printf(
" %d\n " ,query( 1 ,x,y));
        }
    }
    
return   0 ;
}

你可能感兴趣的:(value)