poj 3368 Frequent values#线段树

来源:互联网 发布:网络预约出租车驾驶员 编辑:程序博客网 时间:2024/05/20 22:00
/**一个非降的数组,求区间[i,j]中的最大频度一道求区间内最大值的线段树,只不过这个最大值是经过处理获得的。a[i]   原数组sub[i] 表示原数组下标i在线段树中的位置seg[i] 即线段树中叶子的值,也就是要查询的最大值所在的数组       所表示的值是原数组中第i段相等值得个数。样例:10 3-1 -1 1 1 1 1 3 10 10 10缩数组为下标 1 2 3 4个数 2 4 1 3特殊情况处理,要查询的区间可能只有部分数在线段树中,例如[2,4],这时踢出两个1,即查询[2,2]*/#include <stdio.h>#include <algorithm>using namespace std;#define N 110000#define L(i) i << 1#define R(i) i << 1 | 1int sub[N],seg[N],n;int a[N];struct _st{    int l,r,maxx;    int mid()    {        return (l + r) >> 1;    }}st[N<<2];void build(int id,int l,int r){    st[id].l = l;    st[id].r = r;    int mid = st[id].mid();    if(l == r)    {        st[id].maxx = seg[l];        return ;    }    build(L(id),l,mid);    build(R(id),mid+1,r);    st[id].maxx = max(st[L(id)].maxx,st[R(id)].maxx);}int query(int id,int l,int r){    if(st[id].l == l && r == st[id].r)        return st[id].maxx;    int mid = st[id].mid();    if(mid >= r)        return query(L(id),l,r);    else if(mid < l)        return query(R(id),l,r);    return max(query(L(id),l,mid),query(R(id),mid+1,r));}int main(){    int q,i,j,k;    while(scanf("%d",&n) == 1 && n)    {        scanf("%d",&q);        for(i = 1; i <= n; ++i)            scanf("%d",a + i);        k = 0;        for(i = 1; i <= n; i = j)        {            sub[i] = ++k;            seg[k] = 1;            for(j = i + 1; j <= n && a[j] == a[j-1];++j)                sub[j] = k,seg[k]++;        }        build(1,1,k);        int s,e;        int l,r,t,ans;        while(q--)        {            scanf("%d%d",&s,&e);            l = r = 0;            i = sub[s];            j = sub[e];            if(s > 1 && a[s] == a[s-1])            {                for(;s <= e && a[s] == a[s-1];++l,++s);                ++i;            }            if(e < n && a[e] == a[e+1])            {                for(;e >= s&& a[e] == a[e+1];++r,--e);                --j;            }            t = 0;            if(j > i)                t = query(1,i,j);            else if(j == i)                t = seg[i];            ans = max(t,max(l,r));            printf("%d\n",ans);        }    }    return 0;}

原创粉丝点击