zoukankan      html  css  js  c++  java
  • 【POJ 3264】平衡的阵容【分块】

    题目大意:

    题目链接:http://poj.org/problem?id=3264
    给出一个长度为nn的数列,求第ll位到第rr位的最大值减最小值。


    思路:

    RMQ做法:https://blog.csdn.net/SSL_ZYC/article/details/80422589
    这道题也可以用分块做。当然线段树主席树也都可以。
    简直比分块模板还简单。因为没有修改操作。
    要求llrr之间的最小值,那么就先将这个数列分成n\sqrt{n}块,每块初始化出一个最大值和最小值,时间复杂度O(n)O(n)
    接着对于每次询问,就用分块求出询问区间的最大值和最小值,再两者相减,即为答案。


    代码:

    此代码在POJ上可以AC,但洛谷只能拿40分,应该是编译环境的问题。

    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <cstring>
    #define N 50100
    using namespace std;
    
    int n,m,a[N],t,x,y,L[N],R[N],pos[N],maxn[N],minn[N];
    
    int find_max(int l,int r)  //暴力求l到r之间的最大值
    {
    	int ans=0;
    	for (int i=l;i<=r;i++)
    	 ans=max(ans,a[i]);
    	return ans;
    }
    
    int find_min(int l,int r)  //暴力求l到r之间的最小值
    {
    	int ans=1e9;
    	for (int i=l;i<=r;i++)
    	 ans=min(ans,a[i]);
    	return ans;
    }
    
    int Max(int l,int r)  //求询问区间的最大值
    {
    	int q=pos[l],p=pos[r];
    	if (q==p) return find_max(l,r);
    	int ans=max(find_max(l,R[q]),find_max(L[p],r));
    	for (int i=q+1;i<p;i++)
    	 ans=max(ans,maxn[i]);
    	return ans;
    }
    
    int Min(int l,int r)  //求询问区间的最小值
    {
    	int q=pos[l],p=pos[r];
    	if (q==p) return find_min(l,r);
    	int ans=min(find_min(l,R[q]),find_min(L[p],r));
    	for (int i=q+1;i<p;i++)
    	 ans=min(ans,minn[i]);
    	return ans;
    }
    
    int ask(int l,int r)
    {
    	return Max(l,r)-Min(l,r);
    }
    
    int main()
    {
    	memset(minn,0x3f3f3f3f,sizeof(minn));
    	scanf("%d%d",&n,&m);
    	for (int i=1;i<=n;i++)
    	 scanf("%d",&a[i]);
    	t=(int)sqrt(n);
    	for (int i=1;i<=t;i++)
    	{
    		L[i]=R[i-1]+1;
    		R[i]=i*t;
    	}
    	if (R[t]<n)
    	{
    		L[++t]=R[t-1]+1;
    		R[t]=n;
    	}
    	for (int i=1;i<=t;i++)
    	 for (int j=L[i];j<=R[i];j++)
    	 {
    	 	pos[j]=i;
    	 	maxn[i]=max(maxn[i],a[j]);
    	 	minn[i]=min(minn[i],a[j]);  //初始化每个区间的最大值和最小值
    	 }
    	while (m--)
    	{
    		scanf("%d%d",&x,&y);
    		printf("%d\n",ask(x,y));
    	}
    	return 0;
    } 
    
  • 相关阅读:
    windows任务计划
    PHP创建多级文件夹
    js正则表达式(不断总结中....)
    js随机改变背景颜色
    提高PHP代码质量36计
    PHP中使用Filter进行数据安全过滤
    CSS颜色代码大全
    正则表达式的修饰符
    创建索引视图
    读取xml中的所有文件名
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998581.html
Copyright © 2011-2022 走看看