hdu1806 RMQ

 1 #include <stdio.h>
 2 int d[100005][50];
 3 int max(int a,int b)
 4 {
 5                 if (a>b) return(a);
 6                 return(b);
 7 }
 8 int rmq(int l,int r)
 9 {
10                 int k=0;
11                 while ((1<<(k+1))<=r-l+1) k++;
12                 return(max(d[l][k],d[r-(1<<k)+1][k]));
13 }
14 int main()
15 {
16                 int a[100005],k,n,i,j,p,q,x,y,sum,count[100005],num[100005],right[100005],left[100005];
17                 while (~scanf("%d",&n)&&n!=0)
18                 {
19                                 scanf("%d",&k); 
20                                 for (i=1;i<=n;i++) scanf("%d",&a[i]);
21                                 a[0]=1000001; sum=0;
22                                 for (i=1;i<=n;i++)
23                                                 if (a[i]==a[i-1]) 
24                                                 {
25                                                                 count[sum]++;
26                                 num[i]=sum;
27                                                 }
28                                         else
29                                                 {
30                                                                 right[sum]=i-1;
31                                                                 sum++;
32                                                                 left[sum]=i;
33                                                                 count[sum]=1;
34                                                                 num[i]=sum;
35                                                 }
36                                 right[sum]=n;
37 
38                                 for (i=1;i<=sum;i++) d[i][0]=count[i];
39                                 for (j=1;(1<<j)<=sum;j++)
40                                                 for (i=1;i+(1<<j)-1<=sum;i++)
41                                                 d[i][j]=max(d[i][j-1],d[i+(1<<(j-1))][j-1]);
42 
43                                 for (i=1;i<=k;i++)
44                                 {
45                                                 scanf("%d%d",&p,&q);
46                                                 if (num[p]==num[q]) {printf("%d\n",q-p+1);continue;}
47                                                 x=max(right[num[p]]-p+1,q-left[num[q]]+1);
48                                                 if (right[num[p]]+1==left[num[q]]) y=0; else
49                                                 y=rmq(num[p]+1,num[q]-1);
50                                                 printf("%d\n",max(x,y));
51                                 }
52                 }
53                 return(0);
54 }

http://acm.hdu.edu.cn/showproblem.php?pid=1806

转载于:https://www.cnblogs.com/xiao-xin/articles/3849238.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值