UVA-11235 Frequent values ST table

Keywords: PHP

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2176
Given a non-decreasing sequence Ai, you only need to support one operation: finding the number of occurrences of the most numbers in an interval.
Thought: st table. First, the original sequence A should be divided into blocks. If we synthesize an equal number and regard the number of the blocks as the size of the block, then the number of numbers that appear most in an interval of the original query sequence is not equal to the maximum value of the new query sequence. Of course, we also need to record some other information when merging. See the code comments for details.

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;

int a[100005];//Original sequence
int v[100005];//The value of the merged sequence
int cnt[100005];//Number of occurrences of each value in the merged sequence
int id[100005];//The position of the number i in the sequence after merging
int l[100005];//The first position is the end point of the left interval after the merger
int r[100005];//The first position is at the end of the right interval after merger.
int d[100005][30];//st table
int MAX=1;

void RMQ_init()
{
	int t=log2(MAX);
    for(int i=1;i<=MAX;i++)
        d[i][0]=cnt[i];
    for(int j=1;j<=t;j++)
    {
        for(int i=1;i+(1<<j)-1<=MAX;i++)
            d[i][j]=max(d[i][j-1],d[i+(1<<(j-1))][j-1]);
    }
}

int RMQ(int v1,int v2)
{
    int t=log2(v2-v1+1);
    return max(d[v1][t],d[v2-(1<<t)+1][t]);
}

int main()
{
    int t1,t2;
    int temp;
    while(~scanf("%d",&t1)&&t1)
    {
        scanf("%d",&t2);
        for(int i=1;i<=t1;i++)
            scanf("%d",&a[i]);
        MAX=1;
        v[1]=a[1];
        cnt[1]=1;
        id[1]=1;
        l[1]=1;
        for(int i=2;i<=t1;i++)
        {
            if(a[i]!=v[MAX])
            {
                v[++MAX]=a[i];
                cnt[MAX]=1;
                id[i]=MAX;
                l[i]=i;
                for(int k=i-1;k>=1;k--)
                {
                    if(MAX>=2&&a[k]!=v[MAX-1])
                        break;
                    r[k]=i-1;
                }
            }
            else
            {
                cnt[MAX]++;
                id[i]=MAX;
                l[i]=l[i-1];
            }
            if(i==t1)
            {
                for(int k=t1;k>=1;k--)
                {
                    if(MAX>=2&&a[k]!=v[MAX-1])
                        break;
                    r[k]=i;
                }
            }
        }
        int v1,v2;
        RMQ_init();
        while(t2--)
        {
            scanf("%d%d",&v1,&v2);
            if(id[v1]==id[v2])//The same block
                printf("%d\n",v2-v1+1);
            else if(id[v2]-id[v1]==1)//Adjacent blocks
                printf("%d\n",max(r[v1]-v1+1,v2-l[v2]+1));
            else//Number of Phase Blocks >= 2
                printf("%d\n",max(max(r[v1]-v1+1,v2-l[v2]+1),max(v2-l[v2]+1,RMQ(id[v1]+1,id[v2]-1))));
        }
    }
    return 0;
}

Posted by Cherry on Mon, 07 Oct 2019 18:44:25 -0700