rmq模板
2016-03-12 19:53
295 查看
/* HDU 3183 */ #include<stdio.h> #include<iostream> #include<algorithm> #include<math.h> #include<string.h> using namespace std; const int MAXN=1010; int a[MAXN]; int dp[MAXN][20]; void makeRMQIndex(int n,int b[])//形成最小值下标的RMQ { for(int i=0;i<n;i++) dp[i][0]=i; for(int j=1;(1<<j)<=n;j++) for(int i=0;i+(1<<j)-1<n;i++) dp[i][j]=b[dp[i][j-1]]<=b[dp[i+(1<<(j-1))][j-1]]?dp[i][j-1]:dp[i+(1<<(j-1))][j-1]; //这里一定要加等号,就是相等的时候取下标小的 } int rmqIndex(int s,int v,int b[]) { int k=(int)(log(v-s+1.0)/log(2.0)); return b[dp[s][k]]<=b[dp[v-(1<<k)+1][k]]?dp[s][k]:dp[v-(1<<k)+1][k]; //加等号,取小标小的 } char str[MAXN]; int ans[MAXN]; int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int m; while(scanf("%s%d",&str,&m)!=EOF) { int n=strlen(str); for(int i=0;i<n;i++) a[i]=str[i]-'0'; makeRMQIndex(n,a); int t=0; int temp=0; for(int i=m;i<n;i++)//找n-m个数,每次从[t,i]中找最小的 { t=rmqIndex(t,i,a); ans[temp++]=a[t++]; } t=0; while(t<temp&&ans[t]==0)t++; if(t>=temp)printf("0\n"); else { for(int i=t;i<temp;i++)printf("%d",ans[i]); printf("\n"); } } return 0; }
#include<stdio.h> #include<iostream> #include<math.h> #include<string.h> using namespace std; const int MAXN=50050; int dpmax[MAXN][20]; int dpmin[MAXN][20]; void makeMaxRmq(int n,int b[]) { for(int i=0;i<n;i++) dpmax[i][0]=b[i]; for(int j=1;(1<<j)<=n;j++) for(int i=0;i+(1<<j)-1<n;i++) dpmax[i][j]=max(dpmax[i][j-1],dpmax[i+(1<<(j-1))][j-1]); } int getMax(int u,int v) { int k=(int)(log(v-u+1.0)/log(2.0)); return max(dpmax[u][k],dpmax[v-(1<<k)+1][k]); } void makeMinRmq(int n,int b[]) { for(int i=0;i<n;i++) dpmin[i][0]=b[i]; for(int j=1;(1<<j)<=n;j++) for(int i=0;i+(1<<j)-1<n;i++) dpmin[i][j]=min(dpmin[i][j-1],dpmin[i+(1<<(j-1))][j-1]); } int getMin(int u,int v) { int k=(int)(log(v-u+1.0)/log(2.0)); return min(dpmin[u][k],dpmin[v-(1<<k)+1][k]); } int a[MAXN]; int main() { int n,Q; int u,v; while(scanf("%d%d",&n,&Q)!=EOF) { for(int i=0;i<n;i++) scanf("%d",&a[i]); makeMaxRmq(n,a); makeMinRmq(n,a); while(Q--) { scanf("%d%d",&u,&v); u--; v--; int t1=getMax(u,v); int t2=getMin(u,v); printf("%d\n",t1-t2); } } return 0; }
相关文章推荐
- android 左上角返回上一级的实现
- img的src更改失败原因:JS文件放在了头部引入
- [c++]C++学习笔记001.cout/cin
- cocos2dx_3.X项目重新写(一)帧动画的改变
- Java NIO Channel
- Linux学习计划
- java selenium (六) XPath 定位
- 多线程与runloop
- BZOJ1475方格取数
- flann在Linux平台下的编译
- C++实验1-输出两个数中较大的数
- java selenium (十四) 处理Iframe 中的元素
- java selenium (十三) 智能等待页面加载完成
- java selenium (十二) 操作弹出窗口
- java selenium (十一) 操作弹出对话框
- java selenium (十) 操作浏览器
- java selenium (九) 常见web UI 元素操作 及API使用
- 第三次作业 软件产品同质化问题
- 从本地缓存图片
- BZOJ_P1426 收集邮票(概率+动态规划)