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;
}
posted @ 2008-10-15 19:34  Beetlebum  阅读(570)  评论(1编辑  收藏  举报