zoukankan      html  css  js  c++  java
  • UVa 11235

    RMQ的应用,因为题目给定的数组相同的数字都是在一起,这意味着非常紧凑,借助RMQ,最值只可能有三种情况

    • 频率最高是因为最左边的数
    • 频率最高是因为最右边的数
    • 将整个数组所有相同的数全部放在一个频数数组里面,所询问的区间内完整包含的那些数的频数最值可以利用RMQ来获取
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <string>
    #include <vector>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cstdint>
    #include <cassert>
    #include <cmath>
    #include <string>
    #include <stack>
    #include <map>
    #include <set>
    #include <deque>
    #include <unordered_map>
    using namespace std;
    
    const int INF= 0x3f3f3f3f;
    const int maxn= 1e5+5;
    
    int n, q;
    int a[maxn];
    int L[maxn], R[maxn], idx[maxn];
    int num[maxn];
    int dv[maxn][20];
    int lg[maxn];
    
    void InitRMQ(int a[], int tot)
    {
    	lg[0]= -1;
    	for (int i= 1; i <= tot; ++i){
    		lg[i]= i & (i-1) ? lg[i-1] : lg[i-1]+1;
    		dv[i][0]= a[i];
    	}
    
    	for (int j= 1; j <= lg[tot]; ++j){
    		for (int i= 1; i+(1<<j)-1 <= tot; ++i){
    			dv[i][j]= max(dv[i][j-1], dv[i+(1<<(j-1))][j-1]);
    		}
    	}
    }
    int RMQ(int l, int r)
    {
    	if (l > r){
    		return 0;
    	}
    	int k= lg[r-l+1];
    	return max(dv[l][k], dv[r+1-(1<<k)][k]);
    }
    int main(int argc, char const *argv[])
    {
    	while (~scanf("%d", &n) && n){
    		scanf("%d", &q);
    		for (int i= 1; i <= n; ++i){
    			scanf("%d", a+i);
    		}
    
    		int bg= 1, ed= 1;
    		int tot= 1;
    		for (int i= 1; i <= n; ++i){
    			if (a[i] != a[bg]){
    				ed= i-1;
    				for (int j= bg; j <= ed; ++j){
    					R[j]= ed;
    				}
    				num[tot]= i-bg;
    				++tot;
    				bg= i;
    			}
    			L[i]= bg;
    			idx[i]= tot;
    		}
    		ed= n;
    		for (int i= bg; i <= n; ++i){
    			R[i]= ed;
    		}
    		num[tot]= n+1-bg;
    
    		InitRMQ(num, tot);
    
    		int ans;
    		while (q--){
    			scanf("%d%d", &bg, &ed);
    			if (idx[bg] == idx[ed]){
    				ans= ed-bg+1;
    			} else{
    				ans= max(R[bg]+1-bg, ed+1-L[ed]);
    				ans= max(RMQ(idx[bg]+1, idx[ed]-1), ans);
    			}
    			printf("%d
    ", ans);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    iOS 有用的代码片段
    iOS 限制软盘输入法
    UIlabel 遇到\n 换行iOS
    关于delegate 与 protocol 的理解 iOS
    ios 跳转到app store
    iOS 上下左右滑动手势
    求某段程序运行的高精度时间
    转载——GDB中应该知道的几个调试方法
    文章翻译——使用 GNU 的 GDB调试器,内存布局和栈——01
    第十章扩展——__cdecl 的压栈方式——printf
  • 原文地址:https://www.cnblogs.com/Idi0t-N3/p/15228308.html
Copyright © 2011-2022 走看看