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 2348 Euclid's Game【博弈】
    POJ 2484 A Funny Game【博弈】
    HDU 4193 Non-negative Partial Sums【单调队列】
    占坑补题
    Codeforces 658D Bear and Polynomials【数学】
    Codeforces 658C Bear and Forgotten Tree 3【构造】
    Codeforces 658B Bear and Displayed Friends【set】
    POJ 1704 Georgia and Bob【博弈】
    1001. A+B Format

  • 原文地址:https://www.cnblogs.com/staginner/p/2340262.html
Copyright © 2011-2022 走看看