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
",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
",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
",max(mm,maxz));
75             }
76         }
77     }
78     return 0;
79 }
View Code
原文地址:https://www.cnblogs.com/shangyu/p/3258762.html