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 integeru, v ( 1≤ u< v≤ 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\n"); else printf("%d\n",tmp[ans]); } printf("\n"); } return 0; }