poj 3368
线段树
/*
* 思路:在线段树的结点内设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>
#include<fstream>
using namespace std;
struct e{
int l,r,maxx,maxl,maxr;
}tree[800000];
int n;
int a[100001];
void build(int l,int r,int p){
int i,j,k;
tree[p].l=l;
tree[p].r=r;
tree[p].maxl=0;
tree[p].maxr=0;
for(k=l;k<=r;k++)
if(a[k]==a[l])
tree[p].maxl++;
for(k=r;k>=l;k--)
if(a[k]==a[r])
tree[p].maxr++;
if(l<r){
int mid=(l+r)>>1;
build(l,mid,p*2);
build(mid+1,r,p*2+1);
if(a[mid]==a[mid+1])
tree[p].maxx=max(tree[2*p].maxx,max(tree[2*p+1].maxx,tree[2*p].maxr+tree[2*p+1].maxl));
else
tree[p].maxx=max(tree[2*p].maxx,tree[2*p+1].maxx);
}
else
{
tree[p].maxx=1;
}
}
int b[200001];
int find(int l,int r,int p){
if(l==tree[p].l&&r==tree[p].r)
return tree[p].maxx;
int mid=(tree[p].l+tree[p].r)>>1;
if(r<=mid)
return find(l,r,p*2);
if(l>mid)
return find(l,r,p*2+1);
if(a[mid]==a[mid+1])
{
int j=0,k=0;
for(int i=mid;i>=l;i--)
if(a[mid]==a[i])
j++;
else
break;
for(int i=mid+1;i<=r;i++)
if(a[i]==a[mid+1])
k++;
else
break;
return max(find(l,mid,p*2),max(find(mid+1,r,2*p+1),j+k));
}
else
return max(find(l,mid,p*2),find(mid+1,r,p*2+1));
}
void read(){
// ifstream cin("in.txt");
int i,j,k,s=0,t;
while(1){
// cin>>n;
scanf("%d",&n);
s=0;
if(n==0) return;
// cin>>k;
scanf("%d",&k);
memset(b,0,sizeof(b));
for(i=1;i<=n;i++)
{
// cin>>j;
scanf("%d",&j);
if(b[j+100000]==0)
b[j+100000]=++s;
a[i]=b[j+100000];
}
build(1,n,1);
for(i=1;i<=k;i++)
{
// cin>>j>>t;
scanf("%d%d",&j,&t);
cout<<find(j,t,1)<<endl;
}
}
}
int main(){
read();
return 0;
}
浙公网安备 33010602011771号