zoukankan      html  css  js  c++  java
  • rmq的st算法模板题 nyoj 119

    士兵杀敌(三)

    时间限制:2000 ms  |  内存限制:65535 KB
    难度:5
    描述

    南将军统率着N个士兵,士兵分别编号为1~N,南将军经常爱拿某一段编号内杀敌数最高的人与杀敌数最低的人进行比较,计算出两个人的杀敌数差值,用这种方法一方面能鼓舞杀敌数高的人,另一方面也算是批评杀敌数低的人,起到了很好的效果。

    所以,南将军经常问军师小工第i号士兵到第j号士兵中,杀敌数最高的人与杀敌数最低的人之间军功差值是多少。

    现在,请你写一个程序,帮小工回答南将军每次的询问吧。

    注意,南将军可能询问很多次。

    输入
    只有一组测试数据
    第一行是两个整数N,Q,其中N表示士兵的总数。Q表示南将军询问的次数。(1<N<=100000,1<Q<=1000000)
    随后的一行有N个整数Vi(0<=Vi<100000000),分别表示每个人的杀敌数。
    再之后的Q行,每行有两个正正数m,n,表示南将军询问的是第m号士兵到第n号士兵。
    输出
    对于每次询问,输出第m号士兵到第n号士兵之间所有士兵杀敌数的最大值与最小值的差。
    样例输入
    5 2
    1 2 6 9 3
    1 2
    2 4
    样例输出
    1
    7
    #include<stdio.h>
    #include<math.h>
    #define N 110000
    int ffmax[N][20],ffmin[N][20],num[N];
    int Max(int a,int b) {
    return a>b?a:b;
    }
    int Min(int a,int b) {
    return a>b?b:a;
    }
    void init(int n) {
      int k,i,j,m;
      for(i=1;i<=n;i++) {
        ffmax[i][0]=num[i];
        ffmin[i][0]=num[i];
      }
      k=(int)(log(double(n))/log(2.0));
      for(j=1;j<=k;j++)
      for(i=0;i+(1<<j)-1<=n;i++) {
            m=i+(1<<(j-1));
      ffmax[i][j]=Max(ffmax[i][j-1],ffmax[m][j-1]);
      ffmin[i][j]=Min(ffmin[i][j-1],ffmin[m][j-1]);
      }
      return ;
     }
     void print(int a,int b) {
         int k;
         k=(int)(log(double(b-a+1))/log(2.0));
       int max=Max(ffmax[a][k],ffmax[b-(1<<k)+1][k]);
       int min=Min(ffmin[a][k],ffmin[b-(1<<k)+1][k]);
       printf("%d
    ",max-min);
     }
    int main() {
        int n,m,i,j,k;
        while(scanf("%d%d",&n,&m)!=EOF) {
          for(i=1;i<=n;i++)
                scanf("%d",&num[i]);
          init(n);
          while(m--) {
            scanf("%d%d",&j,&k);
            print(j,k);
          }
        }
    return 0;
    }
    
    标程:
     
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    const int MAX=100010;
    int FMAX[MAX][20],FMIN[MAX][20];
    
    
    int main()
    {
    	int n,q,a,b,v;
    	cin>>n>>q;
    	for(int i=1;i<=n;++i)
    	{
    		scanf("%d",&FMAX[i][0]);
    		FMIN[i][0]=FMAX[i][0];
    	}
    	for(int i=1;i!=20;i++)
    		for(int j=1;j<=n;j++)
    			if(j+(1<<i)-1<=n)
    			{
    				FMAX[j][i]=max(FMAX[j][i-1],FMAX[j+(1<<(i-1))][i-1]);
    				FMIN[j][i]=min(FMIN[j][i-1],FMIN[j+(1<<(i-1))][i-1]);
    			}
    	for(int i=0;i!=q;++i)
    	{
    		scanf("%d%d",&a,&b);
    		int len=(int)(log(b-a+1.0)/log(2.0));
    		printf("%d
    ",max(FMAX[a][len],FMAX[b-(1<<len)+1][len])-min(FMIN[a][len],FMIN[b-(1<<len)+1][len]));
    	}
    }        
    
  • 相关阅读:
    Android系统根文件系统目录结构
    4面 晶晨半导体 问题总结
    linux 工作队列
    Linux tasklet 的测试
    ArbotiX-M引脚说明
    locobot
    视频地址
    S1雷达ROS包更新指南
    rospy
    mx-28在 labview环境下的开发
  • 原文地址:https://www.cnblogs.com/thefirstfeeling/p/4410786.html
Copyright © 2011-2022 走看看