ZOJ 3633

题意:

给出了n个数..

给m个询问..问在询问范围a, b内从右到左第一个出现重复的数..

思路:

用map求出离这个数最近的相同的数的位置..<其实不用map也可以吧~>

然后用rmq求出范围内位置值最大的那个~如果那个位置不在给定范围内或者最大值就是0..代表范围内没有重复的数~就输出OK..

否则输出那个数..

Tips:

用一个数组保存输入的值..

最后就可以根据求出的最大位置..找到这个重复的数..

Code:

View Code
 1 #include <stdio.h>

 2 #include <cstring>

 3 #include <map>

 4 #include <cmath>

 5 #include <iostream>

 6 using namespace std;

 7 #define clr(x) memset(x, 0, sizeof(x))

 8 const int M = 500010;

 9 int dp[M][18];

10 

11 void makermq(int n,int b[])

12 {

13     int i,j;

14     for(i=1;i<=n;i++)

15         dp[i][0]=b[i];

16     for(j=1;(1<<j)<=n;j++)

17         for(i=1;i+(1<<j)-1<=n;i++)

18             dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);

19 }

20 

21 int rmq(int s,int v)

22 {

23     int k=(int)(log((v-s+1)*1.0)/log(2.0));

24     return max(dp[s][k],dp[v-(1<<k)+1][k]);

25 }

26 

27 int arr[500010];

28 int num[500010];

29 int main()

30 {

31     int i, j, k;

32     int n, m;

33     int a, b, tmp;

34     while(cin >> n)

35     {

36         map<int, int> mm;

37         clr(dp);

38         clr(arr);

39         for(i = 1; i <= n; ++i){

40             cin >> num[i];

41             arr[i] = mm[num[i]];

42             mm[num[i]] = i;

43         }

44         makermq(n, arr);

45         cin >> m;

46         while(m--)

47         {

48             cin >> a >> b;

49             tmp = rmq(a, b);

50             if(tmp == 0 || tmp < a || tmp > b) puts("OK");

51             else printf("%d\n", num[tmp]);

52         }

53         puts("");

54     }

55     return 0;

56 }

可能能ac了~因为ZOJ今天刷得很慢~我要睡觉了..

上一次是少了个空行所以PE了~现在应该能ac了~

 

你可能感兴趣的:(ZOJ)