POJ-3368-Frequent values

来源:互联网 发布:linux set environment 编辑:程序博客网 时间:2024/06/05 21:55

给出一个长度为 n 的非降序序列,求区间 [ l , r ] 内数目最多的元素的数目

线段树

#include <iostream>#include <stdio.h>#include <string.h>#include <algorithm>#include <queue>#include <vector>#include <map>#include <cmath>#include <stdlib.h>using namespace std;const double PI = acos(-1.0);const double eps = 0.1;const int MAX = 1e5+10;const int mod = 1e9+7;int n, q, a[MAX], l, r;struct node{    int l, r, lmax, rmax, vmax;    // 区间左右边界, 左最大值, 右最大值,最大值} lxt[MAX*6];void build(int pos, int l, int r){    lxt[pos].l = l;    lxt[pos].r = r;    if(l==r)    {        lxt[pos].lmax = 1;        lxt[pos].rmax = 1;        lxt[pos].vmax = 1;        return;    }    int mid = (l+r)>>1;    build(pos*2, l, mid);    build(pos*2+1, mid+1, r);    lxt[pos].lmax = lxt[pos*2].lmax;    lxt[pos].rmax = lxt[pos*2+1].rmax;    if(a[lxt[pos*2].r]==a[lxt[pos*2+1].l])//如果左子区间最右边的值等于右子区间最左边的值,考虑合并    {        lxt[pos].vmax = lxt[pos*2].rmax+lxt[pos*2+1].lmax;        if(a[lxt[pos].l]==a[lxt[pos*2+1].l])            lxt[pos].lmax = lxt[pos].vmax;        if(a[lxt[pos].r]==a[lxt[pos*2].r])            lxt[pos].rmax = lxt[pos].vmax;    }    else lxt[pos].vmax = 1;    lxt[pos].vmax = max(lxt[pos].vmax, max(lxt[pos*2].vmax, lxt[pos*2+1].vmax));}int solve(int k, int l, int r){    if(l<=lxt[k].l&&lxt[k].r<=r)        return lxt[k].vmax;    if(lxt[k*2].r>=r)return solve(k*2, l, r);    if(lxt[k*2+1].l<=l)return solve(k*2+1, l, r);    int ans1, ans2, ans3;    ans1 = solve(k*2, l, lxt[k*2].r);    ans2 = solve(k*2+1, lxt[k*2+1].l, r);    if(a[lxt[k*2].r]==a[lxt[k*2+1].l])ans3 = min(lxt[k*2].r-l+1,lxt[k*2].rmax)+min(r-lxt[k*2+1].l+1, lxt[k*2+1].lmax);    else ans3 = 1;    return max(ans1, max(ans2, ans3));}int main(){    while(~scanf("%d", &n)&&n)    {        scanf("%d", &q);        for(int i = 1; i<=n; ++i)            scanf("%d", &a[i]);        build(1, 1, n);        while(q--)        {            scanf("%d%d", &l, &r);            printf("%d\n", solve(1, l, r));        }    }    return 0;}


0 0
原创粉丝点击