sugar_free_mint的博客

I am waiting for you!

POJ 3368 Frequent values

题目

求不下降序列的某个区间中出现次数最多的数。


分析

明显的线段树。
用left表示左边的连续个数,right表示右边的连续个数,w表示最长的连续个数。
如果左边的所有数都等于右边最左的数或如果右边的所有数都等于左边最右的数则:
tree[k].right=tree[k2].right+tree[k2+1].left
如果左边最右边的数等于右边最左边的数则最优解在中间:
tree[k].maxs=max(tree[k2].maxs,tree[k2+1].maxs,tree[k2].right+tree[k2+1].left)


代码

#include <cstdio>
#include <cstring>
#define g (k<<1)
using namespace std;
int n,m,b[100001];
struct treen{int left,right,w;}tree[300001];
int max(int a,int b){return (a>b)?a:b;}
int min(int a,int b){return (a<b)?a:b;}
void build(int k,int l,int r){
    if (l==r) tree[k].left=tree[k].right=tree[k].w=1;
    else {
        int mid=(l+r)>>1;
        build(g,l,mid); build(1+g,mid+1,r);
        if (tree[g].left==mid-l+1&&b[mid]==b[mid+1])
        tree[k].left=tree[g].right+tree[1+g].left;
        else tree[k].left=tree[g].left;
        if (tree[1+g].right==r-mid&&b[mid]==b[mid+1])
        tree[k].right=tree[g].right+tree[1+g].left;
        else tree[k].right=tree[1+g].right;
        if (b[mid]==b[mid+1])
        tree[k].w=max(max(tree[g].w,tree[1+g].w),tree[g].right+tree[1+g].left);
        else tree[k].w=max(tree[g].w,tree[1+g].w);
    }
}
int find(int k,int l,int r,int x,int y){
    if (l>y||r<x||r<l) return 0;
    if (l>=x&&r<=y) return tree[k].w;
    int mid=(l+r)>>1; int m=0,m1=0,m2=0;
    if (b[mid]==b[mid+1]) m=min(mid-x+1,tree[g].right)+min(y-mid,tree[1+g].left);
    if (x<=mid) m1=find(g,l,mid,x,y);
    if (y>mid) m2=find(1+g,mid+1,r,x,y);
    return m=max(m,max(m1,m2));
}
int main(){
    while (scanf("%d",&n)&&n){
        scanf("%d",&m); memset(tree,0,sizeof(tree));
        for (int i=1;i<=n;i++) scanf("%d",&b[i]);
        build(1,1,n); int x,y;
        while (m--){
            scanf("%d%d",&x,&y);
            printf("%d\n",find(1,1,n,x,y));
        }
    }
    return 0;
}
阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sugar_free_mint/article/details/80353454
文章标签: POJ 3368 Frequent values
个人分类: 图论 线段树
想对作者说点什么? 我来说一句

Frequent Values(poj 3368) C

2018年01月03日 15KB 下载

没有更多推荐了,返回首页

不良信息举报

POJ 3368 Frequent values

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭