zoukankan      html  css  js  c++  java
  • poj3368 Frequent values ***

    /* 480ms
    * poj-3368.cpp
    * Created on: 2011-10-14
    *
    *
    * RMQ:
    * 10 3
    -1 -1 1 1 1 1 3 10 10 10
    2 3
    1 10
    5 10
    0
    *
    * 1、value[i]:第i个位置的值
    * 2、对每个值,记录该值最后出现的位置,endPoint
    * 3、记录每个值的前面一个值: prePointValue, 如样例中1的前面一个值是-1, 即prePointValue[1] = -1
    * 4、记录每个值出现的次数 frequency, 如样例中frequency[1] = 4
    *
    * 于是对每个询问Q(x, y), 找到ans = max { value[x]出现次数:a1, value[y]出现次数:a2, 位于x,y之间且值不同于value[x]、value[y]的值的frequency:a3 }
    * 注意不同情况, 以上3个值可能有些不用算, 如Q(1, 2), 则a3不用算, 且a1 = a2
    * 应此要分情况讨论
    *
    * 另外, 算a3如果用遍历会TLE, 可以用Sparse—Table
    *
    *  最后,由于值可能为负, 所以最为数组下表时 要加上maxN
    */
    #include <cstdio>
    #include <cstring>
    using namespace std;

    const int maxN = 100000 + 10;
    const int maxK = 20;

    int n, q;
    //如上所述
    int value[maxN], endPoint[2 * maxN], frequency[2 * maxN], prePointValue[2 * maxN];
    //用于Sparse_Table的数据
    int valueNum[2 * maxN], stFre[maxN], d[maxN][maxK], num;

    inline int max(int lhs, int rhs){
    return (stFre[lhs] > stFre[rhs] ? lhs : rhs);
    }

    //ST预处理
    void preST(){
    for(int i=0; i<num; i++)
    d[i][0] = i;

    for(int j=1; (1 << j) <= num; j++)
    for(int i=0; i + (1 << j) - 1 < num; i++)
    d[i][j] = max(d[i][j-1], d[i+(1<<(j-1))][j-1]);
    }

    //ST
    int SparseTable(int x, int y){
    int k;
    for(k=1; (1 << k) <= (y-x+1); k++);
    k--;

    if(stFre[d[x][k]] < stFre[d[y-(1<<k)+1][k]])
    return stFre[d[y-(1<<k)+1][k]];
    else
    return stFre[d[x][k]];
    }



    int main(){
    while(scanf("%d", &n)){
    if(n == 0) return 0;

    memset(frequency, 0, sizeof(frequency));
    num = 0;

    scanf("%d", &q);

    //输入
    //第一个值
    scanf("%d", &value[0]);
    frequency[maxN + value[0]]++;
    valueNum[maxN + value[0]] = num++;

    //1-n的值
    for(int i=1; i<n; i++){
    scanf("%d", &value[i]);
    //输入一个新的值
    if(frequency[maxN + value[i]] == 0){
    //记录上一个值的数据
    endPoint[maxN + value[i-1]] = i-1;
    stFre[valueNum[maxN + value[i-1]]] = frequency[maxN + value[i-1]];

    //记录关于当前新值的数据
    prePointValue[maxN + value[i]] = value[i-1];
    valueNum[maxN + value[i]] = num++;
    }
    frequency[maxN + value[i]]++;
    }
    //记录关于最后一个值得数据
    endPoint[maxN + value[n-1]] = n-1;
    stFre[valueNum[maxN + value[n-1]]] = frequency[maxN + value[n-1]];


    //RMQ
    preST();

    int x, y;
    for(int i=0; i<q; i++){
    scanf("%d %d", &x, &y);

    x--; y--; //注意数组从0开始
    int tmpMax = -1;
    //case 1
    if(value[x] == value[y]) tmpMax = y - x + 1;
    //other cases: 对于样例, 如 Q(1, 2)
    else{
    int xx = valueNum[maxN + value[endPoint[maxN + value[x]] + 1]];
    int yy = valueNum[maxN + prePointValue[maxN + value[y]]];
    //case 2: 对于样例, 如 Q(1, 7) or Q(1, 10) //yy < xx 如 Q(1, 3)
    if(yy >= xx){
    tmpMax = SparseTable(xx, yy);
    }
    //a1
    int xFre = endPoint[maxN + value[x]] - x + 1;
    //a2
    int yFre = y - endPoint[maxN + prePointValue[maxN + value[y]]];

    if(xFre > tmpMax) tmpMax = xFre;
    if(yFre > tmpMax) tmpMax = yFre;
    }

    printf("%d\n", tmpMax);
    }
    }



    return 0;
    }
  • 相关阅读:
    Android实现简单的检测手机自由落体关闭屏幕
    Android Disable Package/Component 跳过app安装
    求单向链表中倒数第k个节点(c++):快慢指针/递归
    算法学习笔记---链表与数组
    pycharm使用matplotlib绘图学习笔记
    pycharm使用matplotlib绘制图像报错
    python numpy学习笔记
    python刷leetcode算法-- 左旋转字符串
    机器学习算法扫盲篇
    Kaggle入门篇
  • 原文地址:https://www.cnblogs.com/longdouhzt/p/2213627.html
Copyright © 2011-2022 走看看