zoukankan      html  css  js  c++  java
  • POJ 3368 Frequent values

    POJ_3368

        本来想找个RMQ问题练一下今天刚学的ST算法,结果这个题我用ST做不出来,所以只好又用回线段树解法了。

        当然dicuss里面有人说也可用ST去做的,我就只说一下我用线段树去做的思路吧。

        首先,如果a[i]==a[j]的话,自然输出j-i+1就可以了,如果a[i]!=a[j],如果我们直接查询a[i]、a[j]之间的所有整数出现的频率的最大值,显然是有问题的,因为这样可能会将值等于a[i]或a[j]但序号并不在i~j的范围的整数也统计在内。于是,我们便有了一个思路,在统计a[i]、a[j]之间的所有整数出现的频率的最大值之前,能不能修改一下a[i]和a[j]出现的频率,使得可以忽略掉i~j范围之外的但值等于a[i]或a[j]的整数呢?思考一下之后,就会发现这是可以做到的。我们只要用一个数组f[i]记录到第i个整数时,在i及i前面一共有多少个和a[i]相等的整数,这样就可以借助f[i]和f[j]的值修改a[i]和a[j]出现的频率了。

    #include<stdio.h>
    #include<string.h>
    #define D 100001
    #define MAXD 200010
    #define INF 0x3f3f3f3f
    int N, M, Q, tree[4 * MAXD], a[MAXD], f[MAXD];
    void build()
    {
    int i, j, k;
    for(i = M; i < 2 * M; i ++)
    tree[i] = 0;
    for(i = 1; i <= N; i ++)
    ++ tree[M + a[i]];
    for(i = M - 1; i > 0; i --)
    tree[i] = tree[2 * i] > tree[2 * i + 1] ? tree[2 * i] : tree[2 * i + 1];
    }
    void init()
    {
    int i, j, k, max = -INF;
    scanf("%d", &Q);
    a[0] = -1;
    for(i = 1; i <= N; i ++)
    {
    scanf("%d", &k);
    a[i] = k + D;
    if(a[i] > max)
    max = a[i];
    f[i] = a[i] == a[i - 1] ? f[i - 1] + 1 : 1;
    }
    for(M = 1; M < max + 2; M <<= 1);
    build();
    }
    void update(int i)
    {
    for(; i ^ 1; i >>= 1)
    tree[i >> 1] = tree[i] > tree[i ^ 1] ? tree[i] : tree[i ^ 1];
    }
    int search(int i, int j)
    {
    int max = 0;
    for(-- i, ++ j; i ^ j ^ 1; i >>= 1, j >>= 1)
    {
    if((~i & 1) && tree[i ^ 1] > max)
    max = tree[i ^ 1];
    if((j & 1) && tree[j ^ 1] > max)
    max = tree[j ^ 1];
    }
    return max;
    }
    void solve()
    {
    int i, j, k, x, y, t1, t2;
    for(i = 0; i < Q; i ++)
    {
    scanf("%d%d", &x, &y);
    if(a[x] == a[y])
    printf("%d\n", y - x + 1);
    else
    {
    t1 = tree[a[x] + M], t2 = tree[a[y] + M];
    tree[a[x] + M] = t1 - f[x] + 1;
    update(a[x] + M);
    tree[a[y] + M] = f[y], update(a[y] + M);
    printf("%d\n", search(a[x] + M, a[y] + M));
    tree[a[x] + M] = t1, update(a[x] + M);
    tree[a[y] + M] = t2, update(a[y] + M);
    }
    }
    }
    int main()
    {
    for(;;)
    {
    scanf("%d", &N);
    if(!N)
    break;
    init();
    solve();
    }
    return 0;
    }


  • 相关阅读:
    POJ 1328 Radar Installation
    POJ 1700 Crossing River
    POJ 1700 Crossing River
    poj 3253 Fence Repair (贪心,优先队列)
    poj 3253 Fence Repair (贪心,优先队列)
    poj 3069 Saruman's Army(贪心)
    poj 3069 Saruman's Army(贪心)
    Redis 笔记与总结2 String 类型和 Hash 类型
    数据分析方法有哪些_数据分析方法
    数据分析方法有哪些_数据分析方法
  • 原文地址:https://www.cnblogs.com/staginner/p/2340262.html
Copyright © 2011-2022 走看看