ZOJ 3633 Alice's present 倍增 区间查询最大值

Alice's present

Time Limit: 1 Sec  

Memory Limit: 256 MB

题目连接

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=95030#problem/A

Description

As a doll master, Alice owns a wide range of dolls, and each of them has a number tip on it's back, the tip can be treated as a positive integer. (the number can be repeated). One day, Alice hears that her best friend Marisa's birthday is coming , so she decides to sent Marisa some dolls for present. Alice puts her dolls in a row and marks them from 1 to n. Each time Alice chooses an interval from i to j in the sequence ( include i and j ) , and then checks the number tips on dolls in the interval from right to left. If any number appears more than once , Alice will treat this interval as unsuitable. Otherwise, this interval will be treated as suitable.

This work is so boring and it will waste Alice a lot of time. So Alice asks you for help .

Input

There are multiple test cases. For each test case:

The first line contains an integer n ( 3≤ n ≤ 500,000) ,indicate the number of dolls which Alice owns.

The second line contains n positive integers , decribe the number tips on dolls. All of them are less than 2^31-1. The third line contains an interger m ( 1 ≤ m ≤ 50,000 ),indicate how many intervals Alice will query. Then followed by m lines, each line contains two integer u, v ( 1≤ u< vn ),indicate the left endpoint and right endpoint of the interval. Process to the end of input.

,Ci​​,即此题的初始分值、每分钟减少的分值、dxy做这道题需要花费的时间。

Output

For each test case:

For each query, If this interval is suitable , print one line "OK". Otherwise, print one line ,the integer which appears more than once first.

Print an blank line after each case.

Sample Input

5
1 2 3 1 2
3
1 4
1 5
3 5
6
1 2 3 3 2 1
4
1 4
2 5
3 6
4 6

Sample Output

1
2
OK

3
3
3
OK

HINT

题意

查询一个区间是否有重复,以及从右边开始,第一个重复的数是什么

题解:

直接记录pre就好了

然后st区间查询最大值就好了

代码:

#include<stdio.h>
#include<iostream>
#include<cstring>
#include<map>
using namespace std;
#define maxn 500500
int a[500500];
int dp[maxn][20];
int mm[maxn];
int val[maxn];
void initrmp(int n)
{
    mm[0]=-1;
    for(int i=1;i<=n;i++)
    {
        mm[i]=((i&(i-1))==0)?mm[i-1]+1:mm[i-1];
        dp[i][0]=val[i];
    }
    for(int j = 1;j<=mm[n];j++)
        for(int i=1;i+(1<<j)-1<=n;i++)
            dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
}
int query(int l,int r)
{
    int k = mm[r-l+1];
    return max(dp[l][k],dp[r-(1<<k)+1][k]);
}
map<int,int> H;
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        memset(mm,0,sizeof(mm));
        memset(val,0,sizeof(val));
        memset(dp,0,sizeof(dp));
        memset(a,0,sizeof(a));
        H.clear();
        //int n;scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        for(int i=1;i<=n;i++)
        {
            val[i]=H[a[i]];
            H[a[i]]=i;
        }
        initrmp(n);
        int m;scanf("%d",&m);
        while(m--)
        {
            int l ,r;
            scanf("%d%d",&l,&r);
            int p = query(l,r);
            if(p<l)printf("OK
");
            else printf("%d
",a[p]);
        }
        printf("
");
    }
}
原文地址:https://www.cnblogs.com/qscqesze/p/4876032.html