ZOJ 3633 Alice's present RMQ

 Alice's present

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 jin 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 integeruv ( 1≤ uv≤ n ),indicate the left endpoint and right endpoint of the interval. Process to the end of input.

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

题意:

  给你n个数m次询问,每次询问l,r,问你l,r内一个个出现重复的数是多少

题解:

  我们预处理出当前这个数上一次出现的位置,否则是0

  在跑RMQ,找最大位置就好了

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include<map>
using namespace std;
const int N = 5e5+10, M = 30005, mod = 1e9 + 7, inf = 0x3f3f3f3f;
typedef long long ll;
int n,a[N],dp[N][20];
map<int,int> mp;
void RMQ_init() {
    memset(dp,0,sizeof(dp));
    for(int i=1;i<=n;i++) dp[i][0] = a[i];
    for(int j=1;(1<<j)<=n;j++) {
        for(int i=1;i + (1<<j) - 1 <= n; i++) {
            if(dp[i][j-1] > dp[i+(1<<(j-1))][j-1])
                dp[i][j] =  dp[i][j-1];
            else {
                 dp[i][j] =  dp[i+(1<<(j-1))][j-1];
            }
        }
    }
}
int rmq(int l,int r) {
    if(l==r) return a[l];
    int k = (int) (log((double) r-l+1) / log(2.0));
    return max(dp[l][k], dp[r - (1<<k) + 1][k]);
}
int main() {
    //cout<<(1<<19)<<endl;
    while(scanf("%d",&n)!=EOF) {
        int tmp[N];
        tmp[0] = 0;
        for(int i=1;i<=n;i++) scanf("%d",&a[i]), tmp[i] = a[i];
        mp.clear();
        for(int i=1;i<=n;i++) {
            if(mp.count(a[i])) {
               int t = a[i];
                a[i] = mp[t]; mp[t] = i;
            }
            else mp[a[i]] = i, a[i] = 0;
        }
        RMQ_init();
       int q;
        scanf("%d",&q);
        for(int i=1;i<=q;i++) {
            int a,b,ans;
            scanf("%d%d",&a,&b);
            ans = rmq(a,b);
            if(!ans||ans<a||ans>b) printf("OK
");
            else printf("%d
",tmp[ans]);
        }
        printf("
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/zxhl/p/5397117.html