POJ 3368 Frequent values(线段树区间合并)

来源:互联网 发布:东德歧视中国人知乎 编辑:程序博客网 时间:2024/06/05 11:22

传送门:http://poj.org/problem?id=3368
题意:输入一个n个元素排好序的序列,然后输入q个查询。每次查询一个区间,输出这个区间内出现最多次数的数字的次数,但是因为序列已经是排序好的,所以相等的数字一定是相邻的。所以用线段树,记录每个区间的最左边的数字,和最右边的数字,左边的连续长度,右边的连续长度,最长的总长度。然后查询的时候区间合并一下就可以搞了。

#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <cstdlib>#include <cctype>#include <string>#include <iostream>#include <vector>#include <map>#include <queue>#include <ctime>using namespace std;typedef long long LL;typedef pair<int,int> pii;#define PB push_back#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define calm (l+r)>>1const int INF=1e9+7;const int maxn=100000;int ll[maxn<<2],rr[maxn<<2],llen[maxn<<2],rlen[maxn<<2],sum[maxn<<2];int n,m;inline void pushup(int rt){    sum[rt]=max(sum[rt<<1],sum[rt<<1|1]);    ll[rt]=ll[rt<<1];   rr[rt]=rr[rt<<1|1];    llen[rt]=llen[rt<<1];   rlen[rt]=rlen[rt<<1|1];    if(ll[rt<<1]==rr[rt<<1]){        if(rr[rt<<1]==ll[rt<<1|1]){            llen[rt]=llen[rt<<1]+llen[rt<<1|1];        }    }    if(ll[rt<<1|1]==rr[rt<<1|1]){        if(ll[rt<<1|1]==rr[rt<<1]){            rlen[rt]=rlen[rt<<1|1]+rlen[rt<<1];        }    }    if(rr[rt<<1]==ll[rt<<1|1]){        sum[rt]=max(sum[rt],rlen[rt<<1]+llen[rt<<1|1]);    }    sum[rt]=max(sum[rt],max(llen[rt],rlen[rt]));}void build(int l,int r,int rt){    ll[rt]=rr[rt]=llen[rt]=rlen[rt]=sum[rt]=0;    if(l==r){        int x;scanf("%d",&x);        ll[rt]=rr[rt]=x;        llen[rt]=rlen[rt]=sum[rt]=1;        return;    }    int m=calm;    build(lson);build(rson);    pushup(rt);}struct node{    int ll,rr,llen,rlen,sum;    node(){}    node(int ll,int rr,int llen,int rlen,int sum):ll(ll),rr(rr),llen(llen),rlen(rlen),sum(sum){}};node merge(node left,node right){    node ans;    ans.sum=max(left.sum,right.sum);    ans.ll=left.ll; ans.rr=right.rr;    ans.llen=left.llen; ans.rlen=right.rlen;    if(left.ll==left.rr){        if(left.rr==right.ll){            ans.llen=left.llen+right.llen;        }    }    if(right.ll==right.rr){        if(left.rr==right.ll){            ans.rlen=left.rlen+right.rlen;        }    }    if(left.rr==right.ll){        ans.sum=max(ans.sum,left.rlen+right.llen);    }    ans.sum=max(ans.sum,max(ans.llen,ans.rlen));    return ans;}node query(int L,int R,int l,int r,int rt){    if(L<=l&&r<=R){        return node(ll[rt],rr[rt],llen[rt],rlen[rt],sum[rt]);    }    int m=calm;    if(R<=m)return query(L,R,lson);    if(L>m)return query(L,R,rson);    return merge(query(L,R,lson),query(L,R,rson));}int main(){    //freopen("input.txt","r",stdin);    while(scanf("%d",&n)!=EOF){        if(n==0)break;        scanf("%d",&m);        build(1,n,1);        while(m--){            int L,R;scanf("%d%d",&L,&R);            printf("%d\n",query(L,R,1,n,1).sum);        }    }    //printf("[Run in %.1fs]\n",(double)clock()/CLOCKS_PER_SEC);    return 0;}
0 0
原创粉丝点击