现在的位置: 首页 > 综合 > 正文

poj-3368 Frequent values ***

2012年08月03日 ⁄ 综合 ⁄ 共 2215字 ⁄ 字号 评论关闭
/* 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;
}

抱歉!评论已关闭.