当前位置:编程学习 > C/C++ >>

POJ 3368 Frequent values(线段树)

这一个题目是求一个区间内重复数字的最大次数。

这题有一个特点,数字是递增滴,相同的数字肯定是连续的。

将相同的数字看做一个部分,hash保存每个数字属于哪个部分。对所有的部分建一颗二叉树,保存此区间内最大的重复数字的个数。

 

查询的时候分3中情况

1 在同一个部分,直接 尾 - 头 + 1就是结果

2 只差一个部分,分开算,在各个部分里面重复多少次,比较一下

3 中间有很多个部分,那么可以先根据2计算出两头的,在通过二叉树查询最大的重复数字个数

 

#include <iostream>   
#include <algorithm>   
#include <cmath>   
#include <cstdio>   
#include <cstdlib>   
#include <cstring>   
#include <string>   
#include <vector>   
#include <set>   
#include <map>   
#include <queue>   
#include <stack>   
#include <climits>//形如INT_MAX一类的   
#define MAX 100050   
#define INF 0x7FFFFFFF   
#define REP(i,s,t) for(int i=(s);i<=(t);++i)   
#define ll long long   
#define mem(a,b) memset(a,b,sizeof(a))   
#define mp(a,b) make_pair(a,b)   
#define L(x) x<<1   
#define R(x) x<<1|1   
# define eps 1e-5   
//#pragma comment(linker, "/STACK:36777216") ///传说中的外挂   
using namespace std;  
  
struct node {  
    int l,r,mid,value;  
} tree[4*MAX];  
  
struct point {  
    int st,end;  
} cnt[MAX];  
int data[MAX],vis[MAX],maxx;  
  
void up(int num) {  
    tree[num].value = max(tree[L(num)].value ,tree[R(num)].value);  
}  
  
void build(int l,int r,int num) {  
    tree[num].l = l;  
    tree[num].r = r;  
    tree[num].mid = (l+r) >> 1;  
    if(l == r) {  
        tree[num].value = cnt[l].end - cnt[l].st + 1;  
        return ;  
    }  
    build(l,tree[num].mid,L(num));  
    build(tree[num].mid+1,r,R(num));  
    up(num);  
}  
  
int query(int l,int r,int num) {  
    if(l <= tree[num].l && r >= tree[num].r) {  
        return tree[num].value;  
    }  
    if(r <= tree[num].mid) {  
        return query(l,r,L(num));  
    } else if( l > tree[num].mid) {  
        return query(l,r,R(num));  
    } else {  
        return max(query(tree[num].mid+1,r,R(num)),query(l,tree[num].mid,L(num)));  
    }  
}  
  
void test(int n) {  
    for(int i=1; i<=3*n; i++) {  
        printf("l:%d r:%d value:%d\n",tree[i].l,tree[i].r,tree[i].value);  
    }  
}  
int main()  {  
    int i,n,q,a,b;  
    while(scanf("%d",&n)) {  
        if(n == 0)  
            return 0;  
        scanf("%d",&q);  
        for(i=1; i<=n; i++) {  
            scanf("%d",&data[i]);  
        }  
        memset(vis,0,n);  
        int t = 1;  
        cnt[t].st = 1;  
        vis[1] = t;  
        if(n == 1) {  
            cnt[t].end = 1;  
        }  
        for(i=2; i<=n; i++) {  
            if(data[i] != data[i-1]) {  
                cnt[t].end = i-1;  
                t++;  
                cnt[t].st = i;  
                vis[i] = t;  
            } else {  
                vis[i] = t;  
            }  
        }  
        cnt[t].end = n;  
        vis[n] = t;  
  
        build(1,t,1);  
        //test(t);   
        for(i=1; i<=q; i++) {  
            scanf("%d%d",&a,&b);  
            if(vis[a] == vis[b]) {  
                printf("%d\n",b - a+1);  
                continue;  
            }  
            if(vis[b] - vis[a] == 1) {  
                printf("%d\n",max(cnt[vis[a]].end - a+1,b - cnt[vis[b]].st + 1));  
                continue;  
            }  
            int p = max(cnt[vis[a]].end - a+1,b - cnt[vis[b]].st + 1);  
            printf("%d\n",max(p,query(vis[a]+1,vis[b]-1,1)));  
        }  
    }  
    return 0;  
}  

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <climits>//形如INT_MAX一类的
#define MAX 100050
#define INF 0x7FFFFFFF
#define REP(i,s,t) for(int i=(s);i<=(t);++i)
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
#define mp(a,b) make_pair(a,b)
#define L(x) x<<1
#define R(x) x<<1|1
# define eps 1e-5
//#pragma comment(linker, "/STACK:36777216") ///传说中的外挂
using namespace std;

struct node {
    int l,r,mid,value;
} tree[4*MAX];

struct point {
    int st,end;
} cnt[MAX];
int data[MAX],vis[MAX],maxx;

void up(int num) {
    tree[num].value = max(tree[L(num)].value ,tree[R(num)].value);
}

void build(int l,int r,int num) {
    tree[num].l = l;
    tree[num].r = r;
    tree[num].mid = (l+r) >> 1;
    if(l == r) {
        tree[num].value = cnt[l].end - cnt[l].st + 1;
        return ;
    }
    build(l,tree[num].mid,L(num));
    build(tree[num].mid+1,r,R(num));
    up(num);
}

int query(int l,int r,int num) {
    if(l <= tree[num].l && r >= tree[num].r) {
        return tree[num].value;
    }
    if(r <= tree[num].mid) {
        return query(l,r,L(num));
    } else if( l > tree[num].mid) {
        return query(l,r,R(num));
    } else {
        return max(query(tree[num].mid+1,r,R(num)),query(l,tree[num].mid,L(num)));
    }
}

void test(int n) {
    for(int i=1; i<=3*n; i++) {
        printf("l:%d r:%d value:%d\n",tree[i].l,tree[i].r,tree[i].value);
    }
}
int main()  {
    int i,n,q,a,b;
    while(scanf("%d",&n)) {
        if(n == 0)
            return 0;
        scanf("%d",&q);
        for(i=1; i<=n; i++) {
            scanf("%d",&data[i]);
        }
        memset(vis,0,n);
        int t = 1;
        cnt[t].st = 1;
        vis[1] = t;
        if(n == 1) {
            cnt[t].end = 1;
        }
        for(i=2; i<=n; i++) {
            if(data[i] != data[i-1]) {
                cnt[t].end = i-1;
                t++;
                cnt[t].st = i;
                vis[i] = t;
            } else {
                vis[i] = t;
            }
        }
        cnt[t].end = n;
        vis[n] = t;

        build(1,t,1);
        //test(t);
        for(i=1; i<=q; i++) {
            scanf("%d%d",&a,&b);
            if(vis[a] == vis[b]) {
                printf("%d\n",b - a+1);
                continue;
            }
            if(vis[b] - vis[a] == 1) {
                printf("%d\n",max(cnt[vis[a]].end - a+1,b - cnt[vis[b]].st + 1));
                continue;
            }
            int p = max(cnt[vis[a]].end - a+1,b - cnt[vis[b]].st + 1);
            printf("%d\n",max(p,query(vis[a]+1,vis[b]-1,1)));
        }
    }
    return 0;
}


 

补充:软件开发 , C++ ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,