線段樹 (第一次嘗試)

來源:互聯網
上載者:User

A

Time Limit:10000MS  Memory Limit:65536K
Total Submit:94 Accepted:32

Description

有n(1<=n<=100000)個數a1,a2,a3,…,an-1,an(-100000<=ai<=100000), 對於m次(1<=m<=100000)as到at區間的詢問,求該區間的任意兩個數差值的最大值。

Input

輸入由多組資料群組成。每組資料,第1行輸入一個數n;第2行輸入n個整數,每個數後用空格隔開,分別表示a1,a2,……,an-1,an;第3行輸入一個m。第4到m+3行,每行輸入兩個整數s和t(1<=s<=t<=n),表示要查詢的區間為as到at。

Output

對於每個查詢輸出一行,表示該區間內任意兩個數差值的最大值。

Sample Input

510 3 -2 5 -931 52 43 331 3 -531 32 31 2

 

Sample Output

1970882
看到這道題目,像我們這些水手肯定以一般的思路,先建立數組然後然後在要求的數組範圍內全部遍曆一邊,但仔細看看這道題目,這道題目
的限制時間長達10S,時間越多越覺得平常思路不可行,但心裡還是不放心,先嘗試著普通思路做了一遍,很高興的TLE,於是,我問了幾位了
A了的高手們,一位小牛說m才100000;只要運行m*00就不會超,於是有種方法把100000分位以300個數為一個集體的,在每個集體
中記錄最大值和最小值;這樣一來,如果要求首位之間的兩個數之間絕對值最大的就只要遍曆100000/300,所以時間當然OK了,方法也肯巧妙
,時間複雜度也才(m*m/300);但比起線段樹的(m*logm)還是慢了很多,但這題的話可能找最大值最小值找了好幾次,所以時間也不
見得少了很多;
線段樹是在2分分治的基礎上的,它的好處一開始先是作預先處理,然後在進行更新;然後在統計;
具體怎麼樣我也還不怎麼懂,再去做做這類題鞏固鞏固!
My Code如下:
#include<stdio.h>
#define Max(a,b) a > b ? a : b
#define Min(a,b) a > b ? b : a
struct tree
{
 int left;
 int right;
 int mid;
 int max,min;
}seg_tree[500000];
void maketree(int l,int r,int num)
{
 seg_tree[num].left=l;
 seg_tree[num].right=r;
 seg_tree[num].mid=(l+r)/2;
 seg_tree[num].max=-100000;
 seg_tree[num].min=100000;
 if(l+1!=r)
 {
  maketree(l,seg_tree[num].mid,2*num);
  maketree(seg_tree[num].mid,r,2*num+1);
 }
 return ;
}
void insertseg(int i,int value,int num)
{
 if(seg_tree[num].max<value)
  seg_tree[num].max=value;
 if(seg_tree[num].min>value)
     seg_tree[num].min=value;
 if(seg_tree[num].left+1!=seg_tree[num].right)
 {
  if(i<seg_tree[num].mid)
  insertseg(i,value,2*num);
 else insertseg(i,value,2*num+1);
 }
 return ;
}
int findmax(int l,int r,int num)
{
 int x,y;
 if(l==seg_tree[num].left&&r==seg_tree[num].right)
  return seg_tree[num].max;
 if(r<=seg_tree[num].mid)
  return findmax(l,r,num*2);
 if(l>=seg_tree[num].mid)
  return findmax(l,r,num*2+1);
 else
  //return Max(findmax(l,seg_tree[num].mid,num*2),findmax(seg_tree[num].mid,r,num*2+1));
 {
  x = findmax(l,seg_tree[num].mid,num*2);
  y = findmax(seg_tree[num].mid,r,num*2+1);
  return Max(x,y);
 }
}
int findmin(int l,int r,int num)
{
 int x,y;
 if(l==seg_tree[num].left&&r==seg_tree[num].right)
  return seg_tree[num].min;
 if(r<=seg_tree[num].mid)
  return findmin(l,r,num*2);
 if(l>=seg_tree[num].mid)
  return findmin(l,r,num*2+1);
 else
  //return Min(findmin(l,seg_tree[num].mid,num*2),findmin(seg_tree[num].mid,r,num*2+1));
 {
  x = findmin(l,seg_tree[num].mid,num*2);
        y = findmin(seg_tree[num].mid,r,num*2+1);
  return Min(x,y);
 }
}
int main()
{
 int n,i,m;
 int temp,start,end;
 while(scanf("%d",&n)!=EOF)
 {
  maketree(1,n+1,1);
  for(i=1;i<=n;i++)
  {
   scanf("%d",&temp);
   insertseg(i,temp,1);
  }
  scanf("%d",&m);
  while(m--)
  {
   scanf("%d%d",&start,&end);
   printf("%d/n",findmax(start,end+1,1)-findmin(start,end+1,1));
  }
 }
 return 0;
}

 有大牛更好的代碼麻煩留下!!謝謝

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.