生活随笔
收集整理的這篇文章主要介紹了
树状数组求区间最值
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1627: 極差
Time Limit: 1 Sec Memory Limit: 128 MB
[Submit][Status][Web Board]
Description
還記得高中數學的統計部分的極差嗎?既然你能上zcmu計算機及其相關專業,想必計算能力是很厲害的,有一個實驗得到n個數,做實驗的同學經常問你某個區間[L,R]的范圍誤差。(數據范圍[1,100000])
Input
輸入兩個數n,m,第二行n個數,接下來m行[L,R ]
Output
輸出:每一個[L,R]的誤差范圍
Sample Input
3 2
1 5 10
1 2
2 3
Sample Output
4
5
HINT
范圍誤差在數學上用極差表示,極差是區間的最大值與最小值的差
Source
zcc
[Submit][Status][Web Board]
第一次時間超限代碼:
/*
即使我知道百分之90時間超限,但是我有我想鞏固的東西–>為了用用借助結構體封裝數組來實現數組之間賦值
*/
代碼~:
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
typedef struct date
{int num[100005];
} DATE;
DATE a,b;
int main()
{int n,m;while(~scanf("%d%d",&n,&m)){memset(a.num,0,sizeof(a.num));for(int i = 0; i < n; i++){scanf("%d",&a.num[i]);}while(m--){int L,R;scanf("%d%d",&L,&R);b = a;sort(b.num+L-1,b.num+L+R-2);printf("%d\n",b.num[R-1] - b.num[L-1]);}}return 0;
}
下面是AC代碼(效率不知為啥比較低~,耗時1600ms,ac了):
/*
說實話自己對數組數組理解還是比較欠缺(自己還得多研究!!!),
但是我用它來寫,還特意用了函數指針,加深了我對函數指針的理解
*/
AC代碼~:
#include <stdio.h>
#include <algorithm>
using namespace std;
#define max_t 100005
#define Inf 0x3f3f3f3f
int n,m;
int a[max_t],c[max_t],c_max[max_t],c_min[max_t];
int (*f)(int,int);
int Max(int x,int y)
{return x>y?x:y;
}
int Min(int x,int y)
{return x<y?x:y;
}
int lowbit(int x)
{return x&-x;
}
/*int SUM(int y)
{int sum = 0;for(int i = y; i > 0; i-=lowbit(i))sum += c[i];return sum;
}
void update(int x,int k)
{for(int i = x; i <= n; i+=lowbit(i))c[i] += k;
}*/
void up_max_min(int x,int k,int(*f)(int,int),int c_max[])
{for(int i = x; i <= n; i+=lowbit(i))c_max[i] = f(k,c_max[i]);
}
int get_max_min(int L,int R,int(*f)(int,int),int c_max[])
{int y = a[R];while(1){y = f(y,a[R]);if(L==R) break;for(R--; R-L>=lowbit(R); R-=lowbit(R))y = f(y,c_max[R]);}return y;
}
int main()
{while(~scanf("%d%d",&n,&m)){fill(c,c+n+1,0);fill(c_max,c_max+n+1,0);fill(c_min,c_min+n+1,Inf);for(int i = 1; i <= n; i++){scanf("%d",&a[i]);f = Max;up_max_min(i,a[i],f,c_max);f = Min;up_max_min(i,a[i],f,c_min);}while(m--){int L,R,p,q,t;scanf("%d%d",&L,&R);R>L?(t =0):(t=L,L=R,R=t);f = Max;p = get_max_min(L,R,f,c_max);f = Min;q = get_max_min(L,R,f,c_min);printf("%d\n",p-q);}}return 0;
}
總結
以上是生活随笔為你收集整理的树状数组求区间最值的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。