UVA-11235 Frequent values——ST算法+游程编码

Frequent values

Description:
给出一个序列,a1,a2……a3,你的任务是对于一系列询问(i,j),回答ai,……aj中出现次数最多的值所出现的次数。

思路:
这题可以用ST算法,但是没想到主要的编码困难是在数据的预处理。
用结构体struct node{ int value,cnt; node(int v,int c):value(v),cnt(c){} }; 来储存某一段的数字的值,以及出现的次数。

用结构体struct pos{ int index,left,right; pos(int index,int l,int r):index(index),left(l),right(r){} }; 储存某个位置所在段的编号和这一段左右端点的位置

查询时分情况处理:
①L,R在同一段
答案就是 L-R+1
②L,R中间加住了2段及以上
ans应该在
x1 = index( L ).right - L+1
x2 = R-index( R ).left+1
x3 = ST(index( L )+1,index( R )-1)
三者挑出。

#include<stdio.h>
#include<iostream>
#include<cmath>
#include<math.h>
#include<string>
#include<string.h>
#include<algorithm>
#include<stack>
#include<queue>
#include<vector>
#include<map>
#define ms0(a) memset(a,0,sizeof(a))
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;

const int maxn = 1e5+10;
int n,q,d[maxn][20];

struct node{
    int value,cnt;
    node(int v,int c):value(v),cnt(c){}
};
struct pos{
    int index,left,right;
    pos(int index,int l,int r):index(index),left(l),right(r){}
};
void ST_init(const vector<int>& A)
{
    int n = (int)A.size();
    for(int i=0;i<n;i++) d[i][0]=A[i];
    for(int j=1;(1<<j)<=n;j++)
    {
        for(int i=0;i+(1<<j)-1<n;i++)
        {
            d[i][j] = max(d[i][j-1],d[i+(1<<(j-1))][j-1]);
        }
    }
}

int ST(int l,int r)
{
    int k = 0;
    while (1<<(k+1)<=r-l+1) k++;
    return max(d[l][k],d[r-(1<<k)+1][k]);
}

int main(){
    while(~scanf("%d",&n)&&n)
    {
        vector<node> num;vector<pos> a;
        vector<int> A;
        ms0(d);
        int x,y;
        scanf("%d",&q);
        scanf("%d",&x);
        num.push_back(node(x,1));
        for(int i=2;i<=n;i++)
        {
            scanf("%d",&y);
            if(x==y){
                num[num.size()-1].cnt++;
            }
            else{
                num.push_back(node(y, 1));
            }
            x=y;
        }
        int count = 0;
        a.push_back(pos(0,0,0));//填充0位置
        int size = num[0].cnt; count++;
        for(int j=1;j<=size;j++)
            a.push_back(pos(count,1,size));
        for(int i=1;i<num.size();i++)
        {
            int size = num[i].cnt; count++;
            int lastRight = a[a.size()-1].right;
            for(int j=1;j<=size;j++)
            {
                a.push_back(pos(count,lastRight+1, lastRight+size));
            }
        }
        for(int i=0;i<num.size();i++)
            A.push_back(num[i].cnt);
        ST_init(A);
        for(int i=1;i<=q;i++)
        {
            int l,r;
            scanf("%d%d",&l,&r);
            if(a[l].index==a[r].index)
                printf("%d\n",r-l+1);
            else
            {
                int ans = max(a[l].right-l+1,r-a[r].left+1);
                int L = a[l].index+1,R = a[r].index-1;
                ans = max(ans,L<=R?ST(L-1, R-1):0);
                printf("%d\n",ans);
            }
        }
    }
    return 0;
}

发布了78 篇原创文章 · 获赞 0 · 访问量 3414

猜你喜欢

转载自blog.csdn.net/qq_44846324/article/details/104786433