poj2452(RMQ+二分)

题目链接:POJ - 2452

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<algorithm>
 5 using namespace std;
 6 const int maxn=50010;
 7
 8 int qmax[maxn][30],qmin[maxn][30];
 9 int a[maxn];
10 int MIN(int x,int y) //返回下标
11 {
12     if(a[x]<a[y]) return x;
13     else return y;
14 }
15 int MAX(int x,int y)//返回下标
16 {
17     if(a[x]>a[y]) return x;
18     else return y;
19 }
20 void INIT_RMQ(int n)
21 {
22     int k=log2(n);
23     for(int i=0;i<=n;i++)
24         qmax[i][0]=qmin[i][0]=i;
25     for(int j=1;j<=k;j++)
26         for(int i=1;i+(1<<j)-1<=n;i++)
27     {
28         qmax[i][j]=MAX(qmax[i][j-1],qmax[i+(1<<j-1)][j-1]);
29         qmin[i][j]=MIN(qmin[i][j-1],qmin[i+(1<<j-1)][j-1]);
30     }
31     return;
32 }
33
34 int rmqmax(int x,int y)
35 {
36     int k=log2(y-x+1);
37     return MAX(qmax[x][k],qmax[y-(1<<k)+1][k]);
38 }
39 int rmqmin(int x,int y)
40 {
41     int k=log2(y-x+1);
42     return MIN(qmin[x][k],qmin[y-(1<<k)+1][k]);
43 }
44 int BIN(int id,int l,int r)
45 {
46     while(l<=r)
47     {
48         if(l==r) return l;
49         int m=(l+r)>>1;
50         if(a[rmqmin(l,m)]>a[id]) l=m+1;
51         else r=m;
52     }
53 }
54 int main()
55 {
56         int n;
57         while(scanf("%d",&n)!=EOF)
58         {
59             for(int i=1;i<=n;i++)
60                 scanf("%d",&a[i]);
61             INIT_RMQ(n);
62             int ans=0;//二分
63             for(int i=1;i+ans<n;i++)
64             {
65                 int r=BIN(i,i+1,n);
66                 int k=rmqmax(i,r);
67                 if(a[k]>a[i]) ans=max(ans,k-i);
68             }
69             if(ans==0) puts("-1");
70             else printf("%d\n",ans);
71         }
72 }
时间: 2024-10-18 05:51:02

poj2452(RMQ+二分)的相关文章

hdu 5289 Assignment(2015多校第一场第2题)RMQ+二分(或者multiset模拟过程)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5289 题意:给你n个数和k,求有多少的区间使得区间内部任意两个数的差值小于k,输出符合要求的区间个数 思路:求出区间的最大最小值,只要他们的差值小于k,那么这个区间就符合要求,但是由于n较大,用暴力一定超时,所以就要用别的方法了:而RMQ是可以求区间的最值的,而且预处理的复杂度只有O(nlogn),而查询只是O(1)处理,这样相对来说节约了时间,再根据右端点来二分枚举左端点(其实不用二分好像更快,估

HDU 5089 Assignment(rmq+二分 或 单调队列)

Assignment Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 557    Accepted Submission(s): 280 Problem Description Tom owns a company and he is the boss. There are n staffs which are numbered fr

BZOJ 题目3172: [Tjoi2013]单词(AC自动机||AC自动机+fail树||后缀数组暴力||后缀数组+RMQ+二分等五种姿势水过)

3172: [Tjoi2013]单词 Time Limit: 10 Sec  Memory Limit: 512 MB Submit: 1890  Solved: 877 [Submit][Status][Discuss] Description 某人读论文,一篇论文是由许多单词组成.但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次. Input 第一个一个整数N,表示有多少个单词,接下来N行每行一个单词.每个单词由小写字母组成,N<=200,单词长度不超过10^6

玲珑杯 Round 19 B Buildings (RMQ + 二分)

DESCRIPTION There are nn buildings lined up, and the height of the ii-th house is hihi. An inteval [l,r][l,r](l≤r)(l≤r) is harmonious if and only if max(hl,-,hr)?min(hl,-,hr)≤kmax(hl,-,hr)?min(hl,-,hr)≤k. Now you need to calculate the number of harmo

K-th occurrence(后缀树组+划分树+ST表+RMQ+二分)

2019CCPC网络选拔赛1003 HDU6704 题目大意: T个测试样例.一个长度为N的字符串S,之后Q个[l,r,k],表示一个子串S[l,r],求出第k个该子串的下标.起始坐标为1.不存在输出-1. 数据范围:1≤T≤20,  1≤N≤105,  1≤Q≤105,  1≤l≤r≤N,  1≤k≤N,  |S|=N; 赛后补题.参考题解说后缀树组+划分树+ST表+二分. 比赛的时候只会后缀树组不会划分树,赛后仔细想,觉得后缀数组可以,然而并不,会TLE. 补提的时候先是采用后缀树组+划分树

CodeForces 514D R2D2 and Droid Army RMQ+二分

题目链接:点击打开链接 题意:给定n m k 下面是n*m的矩阵 最多可以操作k次,每次操作可以使任意一列上所有的数 -= 1,( 0还是0) 要求得到连续最多的行数(每行里的整数都为0),输出任意一个方案(在每一列上操作的次数) 思路: 把每列单独考虑 枚举每行,二分找这行往下最多能清空的行数, RMQ维护一列的最大值. import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintWr

hdu5289 RMQ+二分

RMQ预处理最大值,最小值,然后对于每一点,二分可能满足的区间长度,长度-1就是该店开始的区间满足的个数. #include<stdio.h> #include<string.h> #include<math.h> #define maxn 100010 #define LL __int64 int dp1[maxn][20],n,a[maxn],dp2[maxn][20]; int min(int x,int y) {return x<y?x:y;} int m

Codeforces #291 (Div. 2) D. R2D2 and Droid Army(RMQ+二分)

题意: 有n*m的矩阵,然后你有k发子弹.现在你可以朝着任意列发射子弹,每一发子弹都会使该列上的数值-1,最小减少到0. 现在问你连续最长的行数,在k发子弹内,使得这些行上的数值全部为0. 思路: 简单的二分枚举最长行数区间,每个区间的最大值决定了要发射的子弹数,所以是RMQ问题,当然这里的枚举全部枚举,用尺取法也可以. //889 ms #include<cstdio> #include<algorithm> #include<cstring> #include<

HDU 5726 GCD (RMQ + 二分)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5726 给你n个数,q个询问,每个询问问你有多少对l r的gcd(a[l] , ... , a[r]) 等于的gcd(a[l'] ,..., a[r']). 先用RMQ预处理gcd,dp[i][j] 表示从i开始2^j个数的gcd. 然后用map存取某个gcd所对应的l r的数量. 我们可以在询问前进行预处理,先枚举i,以i为左端点的gcd(a[i],..., a[r])的种类数不会超过log2(n)