樹狀陣列求區間最值
阿新 • • 發佈:2018-12-07
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; } /*
總結:
不過多解釋,自己還得多研究~
*/