HDU 1806
来源:互联网 发布:王思聪大骂林更新知乎 编辑:程序博客网 时间:2024/05/21 13:58
题意
题意是说给你一个序列,并给你一个区间,让你判断在这个区间中连续相同的数最多有多少个,我第一眼看觉得很简单就暴力 然而现实给了我一记重重的耳光 超时。 本题应该用RMQ来解,因为它有很多次询问 如果暴力会重复的进行很多计算,线段数可以很好的解决。
在编写过程中应该注意构建线段树的时候不要超内存 在运用位运算的时候注意括号,因为为<<”运算级别比“+” “ -”低;
解本题还有一个技巧 就是把以每一个数结尾的时候把他有多少个相同的记录下来 然后就可以用线段树来找当中最大的数 这个数就是答案;如 1 1 1 1 2 3 4 4 记录数组就是1 2 3 4 1 1 1 2
以下是AC代码;
#include <iostream>#include <stdio.h>#include <string.h>using namespace std;int a[100020],a1[100020],dp[100020][20];int main (){ int n,q,i,k,l,r; while (scanf ("%d",&n)!=EOF){ if(n==0) break; scanf ("%d",&q); memset(a1,0,sizeof(a1)); memset(dp,0,sizeof(dp)); for (i=1;i<=n;i++) scanf("%d",&a[i]); a1[1]=1;dp[1][0]=1; for (i=2;i<=n;i++){ if(a[i]==a[i-1]) {a1[i]=a1[i-1]+1; dp[i][0]=a1[i];} else {a1[i]=1; dp[i][0]=1;} } for (k=1;(1<<k)<=n;k++){ for (i=1;i+(1<<k-1)<=n;i++){ dp[i][k]=max(dp[i][k-1],dp[i+(1<<(k-1))][k-1]); } } while (q--){ int sum=0; scanf("%d %d",&l,&r); for (;a1[l]>1&&l<=r;){ if(a1[l]>1){ sum++; l++; } else break; } if(l>=r&&sum==0) printf ("%d\n",sum+1); else if(l>=r&&sum!=0) printf ("%d\n",sum); else { for (k=1;(1<<k)<=r-l;k++);k--; int ma1=max(dp[l][k],dp[r-(1<<k)+1][k]); int ans=max(ma1,sum); printf ("%d\n",ans); } } } return 0;}
0 0
- hdu 1806
- hdu 1806
- hdu 1806
- HDU 1806
- hdu 1806 RMQ
- HDU 1806 :Frequent values
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- PHP判断变量是否为空的几种方法区别
- 7种形式的Android Dialog使用举例
- VMware中虚拟机复制克隆已有系统图文教程 1分钟学会
- 哈夫曼编码(基于哈夫曼树-最优二叉树,不唯一)、B树(b-树)、B+树
- HDU-4027 Can you answer these queries?(线段树专题)
- HDU 1806
- python读取excel文件
- 回看JSP——Cookie的用法
- GF(01)
- 关于含有指针成员的类的对象之间赋值指针的问题。
- Java 之 线程的生命周期(二)
- HBASE RPC 源码实现及解析
- 链表:画图说明问题-
- YII如何隐藏URL中的index.php