poj3368Frequent values(RMQ)

http://poj.org/problem?id=3368

追完韩剧 想起这题来了 想用线段树搞定来着 结果没想出来。。然后想RMQ 想出来了

算是离散吧 把每个数出现的次数以及开始的位置及结束的位置记录下来 以次数进行RMQ 再特殊处理下区间端点就OK 了

WA一次 盯了半小时 原来少了个=号  好吧好吧。。

 1 #include <iostream>

 2 #include<cstdio>

 3 #include<cstring>

 4 #include<algorithm>

 5 #include<stdlib.h>

 6 #include<cmath>

 7 using namespace std;

 8 #define N 200005

 9 struct node

10 {

11     int s,e,a;

12 }p[N];

13 int b[N],f[N],fm[N][40];

14 void init(int n)

15 {

16     int i,j,o = floor(log10(double(n))/log10(double(2)));

17     for(j = 1; j <= o ; j++)

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

19         {

20             fm[i][j] = max(fm[i][j-1],fm[i+(1<<(j-1))][j-1]);

21         }

22 }

23 int main()

24 {

25     int i,n,q;

26     while(scanf("%d",&n)&&n)

27     {

28         scanf("%d",&q);

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

30         {

31             scanf("%d",&b[i]);

32         }

33         int g = 0;

34         p[++g].a = b[1];

35         p[g].s = 1;f[1] = 1;

36         int pre = b[1];

37         for(i = 2; i <= n ; i++)

38         {

39             if(b[i]!=pre)

40             {

41                 p[g].e = i-1;

42                 p[++g].a = b[i];

43                 p[g].s = i;

44                 pre = b[i];

45             }

46             f[i] = g;

47         }

48         p[g].e = n;

49         for(i = 1; i <= g ; i++)

50         fm[i][0] = p[i].e-p[i].s+1;

51         init(g);

52         while(q--)

53         {

54             int a,b,t;

55             scanf("%d%d",&a,&b);

56             if(a>b)

57             {

58                 t = a;a=b;b=t;

59             }

60             int x = f[a],y = f[b];

61             if(x==y)

62             printf("%d\n",b-a+1);

63             else if(y-x==1)

64             {

65                 int maxz = max(b-p[y].s+1,p[x].e-a+1);

66                 printf("%d\n",maxz);

67             }

68             else

69             {

70                 int maxz = max(b-p[y].s+1,p[x].e-a+1);

71                 x++;y--;

72                 int o = floor(log10(double(y-x+1))/log10(double(2)));

73                 int mm = max(fm[x][o],fm[y-(1<<o)+1][o]);

74                 printf("%d\n",max(mm,maxz));

75             }

76         }

77     }

78     return 0;

79 }
View Code

 

你可能感兴趣的:(value)