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;
}
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;
}