HDOJ 题目5289 Assignment(RMQ,技巧)

Assignment

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

Total Submission(s): 1870    Accepted Submission(s): 916

Problem Description

Tom owns a company and he is the boss. There are n staffs which are numbered from 1 to n in this company, and every staff has a ability. Now, Tom is going to assign a special task to some staffs who were in the same group. In a group,
the difference of the ability of any two staff is less than k, and their numbers are continuous. Tom want to know the number of groups like this.

Input

In the first line a number T indicates the number of test cases. Then for each case the first line contain 2 numbers n, k (1<=n<=100000, 0<k<=10^9),indicate the company has n persons, k means the maximum difference between abilities
of staff in a group is less than k. The second line contains n integers:a[1],a[2],…,a[n](0<=a[i]<=10^9),indicate the i-th staff’s ability.

Output

For each test,output the number of groups.

Sample Input

2
4 2
3 1 2 4
10 5
0 3 4 5 2 1 6 7 8 9

Sample Output

5
28

Hint

First Sample, the satisfied groups include:[1,1]、[2,2]、[3,3]、[4,4] 、[2,3] 

Author

FZUACM

Source

2015 Multi-University Training Contest 1

Recommend

We have carefully selected several similar problems for you:  5315 5314 5313 5312 5311

题目大意:输入n,k,问n个数的序列。有多少个区间,最大值减最小值小于k

暴力找区间超时一次

ac代码,跑了1000ms

#include<stdio.h>
#include<string.h>
#include<math.h>
#define max(a,b) (a>b?a:b)
#define min(a,b) (a>b?b:a)
int n;
__int64 m;
__int64 a[100010];
__int64 maxv[100010][20],minv[100010][20];
void init()
{
	int i,j,k;
	for(i=1;i<=n;i++)
	{
		minv[i][0]=a[i];
		maxv[i][0]=a[i];
	}
	for(j=1;(1<<j)<=n;j++)
	{
		for(k=0;k+(1<<j)-1<=n;k++)
		{
			minv[k][j]=min(minv[k][j-1],minv[k+(1<<(j-1))][j-1]);
			maxv[k][j]=max(maxv[k][j-1],maxv[k+(1<<(j-1))][j-1]);
		}
	}
}
__int64 q_max(int l,int r)
{
	int k=(int)(log((double)(r-l+1))/log(2.0));
	return max(maxv[l][k],maxv[r-(1<<k)+1][k]);
}
__int64 q_min(int l,int r)
{
	int k=(int)(log((double)(r-l+1))/log(2.0));
	return min(minv[l][k],minv[r-(1<<k)+1][k]);
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d%I64d",&n,&m);
		int i,j,k;
		for(i=1;i<=n;i++)
		{
			scanf("%I64d",&a[i]);
		}
		init();
		__int64 ans=0;
		int p=1;
		/*for(i=1;i<=n;i++)//暴力超时
		{
			for(j=i;j<=n;j++)
			{
				if(q_max(i,j)-q_min(i,j)<m)
					ans++;
			}
		}*/
		for(i=1;i<=n;i++)
		{
			while(q_max(p,i)-q_min(p,i)>=m&&p<i)
			{
				p++;
			}
			ans+=i-p+1;
		}
		printf("%I64d\n",ans);
	}
}

网上看到用deque做的,跑了577ms,收藏一下,http://www.bubuko.com/infodetail-987302.html

#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std ;
#define LL __int64
deque <LL> deq1 , deq2 ;
//单调队列,deq1最大值,deq2最小值
LL a[100010] ;
int main() {
    int t , n , i , j ;
    LL k , ans ;
    scanf("%d", &t) ;
    while( t-- ) {
        scanf("%d %I64d", &n, &k) ;
        for(i = 0 ; i < n ; i++)
            scanf("%I64d", &a[i]) ;
        if(k == 0) {
            printf("0\n") ;
            continue ;
        }
        while( !deq1.empty() ) deq1.pop_back() ;
        while( !deq2.empty() ) deq2.pop_back() ;
        for(i = 0 , j = 0 , ans = 0; i < n ; i++) {//i在前。j在后
            while( !deq1.empty() && deq1.back() < a[i] ) deq1.pop_back() ;
            deq1.push_back(a[i]) ;
            while( !deq2.empty() && deq2.back() > a[i] ) deq2.pop_back() ;
            deq2.push_back(a[i]) ;
            while( !deq1.empty() && !deq2.empty() && deq1.front() - deq2.front() >= k ) {
                ans += (i-j) ;
                //printf("%d %d,%I64d %I64d\n", i , j, deq1.front() , deq2.front() ) ;
                if( deq1.front() == a[j] ) deq1.pop_front() ;
                if( deq2.front() == a[j] ) deq2.pop_front() ;
                j++ ;
            }
        }
        while( j < n ) {
            ans += (i-j) ;
            j++ ;
        }
        printf("%I64d\n", ans) ;
    }
    return 0 ;
}

时间: 2024-08-28 10:22:32

HDOJ 题目5289 Assignment(RMQ,技巧)的相关文章

HDU - 5289 Assignment (RMQ+二分)

题目链接: Assignment  题意: 给出一个数列,问其中存在多少连续子序列,使得子序列的最大值-最小值<k. 题解: RMQ先处理出每个区间的最大值和最小值(复杂度为:n×logn),相当于求出了每个区间的最大值-最小值.那么现在我们枚举左端点,二分右端点就可以在n×logn×logn的时间内过. 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int MAX_N = 1e5+9; 4 int vec[MAX_N]

5289 Assignment (RMQ+二分区间)

题目链接:5289 Assignment 题意:给出n和K,表示有一串n个数的序列,存在多少个区间,该区间中任意两个数的差小于k 思路: 1.区间任意两个数的小于K 等价于 区间max-min<k,用RMQ来维护,区间最大最小值 2.最后暴力枚举区间必定要超时,发现随着区间的扩大max-min的值也在变大(非递减),有单调性就容易想到二分,所以是枚举左端点,二分找右端点. AC代码: #include<stdio.h> #include <algorithm> using n

hdu 5289 Assignment 二分+rmq

链接:http://acm.hdu.edu.cn/showproblem.php?pid=5289 Assignment Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 332    Accepted Submission(s): 169 Problem Description Tom owns a company and he is

HDOJ 题目3966 Aragorn&#39;s Story(Link Cut Tree成段加减点权,查询点权)

Aragorn's Story Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 5505    Accepted Submission(s): 1441 Problem Description Our protagonist is the handsome human prince Aragorn comes from The Lor

HDOJ 题目4738 Caocao&#39;s Bridges(双联通,求桥)

Caocao's Bridges Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1752    Accepted Submission(s): 642 Problem Description Caocao was defeated by Zhuge Liang and Zhou Yu in the battle of Chibi. B

HDOJ题目3729 I&#39;m Telling the Truth(二分图)

I'm Telling the Truth Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1629    Accepted Submission(s): 805 Problem Description After this year's college-entrance exam, the teacher did a survey i

HDOJ 3486 Interviewe ST RMQ

http://acm.hdu.edu.cn/showproblem.php?pid=3486题意:n个人,有顺序,每个人有自己的能力值.你要从中选m个,分成每段长度[n/m]的小段,如果不能整除,多余的最后那段舍弃.每个小段取能力值最大的那个人.所取的人的能力值之和要大于k,问最少的m是多少. 分析:考虑种种做法,均不可行,然后绕回rmq上.n有20w,虽然st可以o(nlogn)预处理o(1)查询,但是如果枚举m,那么每次查询是m次,最坏可是o(n^2)的复杂度.只好无奈看题解了,结果正解就是

HDOJ 题目4349 Xiao Ming&#39;s Hope(找规律)

Xiao Ming's Hope Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1515    Accepted Submission(s): 1015 Problem Description Xiao Ming likes counting numbers very much, especially he is fond of co

HDOJ 题目分类

HDOJ 题目分类 /* * 一:简单题 */ 1000:    入门用:1001:    用高斯求和公式要防溢出1004:1012:1013:    对9取余好了1017:1021:1027:    用STL中的next_permutation()1029:1032:1037:1039:1040:1056:1064:1065:1076:    闰年 1084:1085:1089,1090,1091,1092,1093,1094, 1095, 1096:全是A+B1108:1157:1196:1