一个简单的线段树,憋了我好久。问题出在了存数据的数组开得不够,因为我建立线段树时要从D-1开始,但是D那一行的元素个数,可能会超过50000所以,存数据的数组要开的大一些。
1 #include<stdio.h> 2 #define INF 1000000000 3 4 int n, m,D,a[(50000+1000)<<1],treemin[51000<<2], treemax[51000<<2]; 5 6 void build() 7 { 8 for(int i = D-1; i > 0; i --) 9 { 10 if(treemin[i<<1] > n || treemin[i<<1] == 0) a[treemin[i<<1]] = INF; 11 if(treemin[i<<1|1] > n || treemin[i<<1|1] == 0) a[treemin[i<<1|1]] = INF; 12 treemin[i] = (a[treemin[i<<1]]<a[treemin[i<<1|1]] ? treemin[i<<1] : treemin[i<<1|1]); 13 14 if(treemax[i<<1] > n || treemax[i<<1] == 0) a[treemax[i<<1]] = -1; 15 if(treemax[i<<1|1] > n || treemax[i<<1|1] == 0) a[treemax[i<<1|1]] = -1; 16 treemax[i] = (a[treemax[i<<1]]>a[treemax[i<<1|1]] ? treemax[i<<1] : treemax[i<<1|1]); 17 } 18 } 19 20 void querymax(int cur, int x, int y, int s, int t, int& ans1) 21 { 22 int mid = (x + y) >> 1, ls = cur << 1, rs = cur << 1 | 1; 23 if(x >= s && y <= t) 24 { 25 if(a[treemax[cur]] > ans1) ans1 = a[treemax[cur]]; 26 return ; 27 } 28 if(mid >= s) 29 querymax(ls, x, mid, s, t, ans1); 30 if(mid + 1 <= t) 31 querymax(rs, mid + 1, y, s, t, ans1); 32 } 33 34 void querymin(int cur, int x, int y, int s, int t, int& ans2) 35 { 36 int mid = (x + y) >> 1, ls = cur << 1, rs = cur << 1 | 1; 37 if(x >= s && y <= t) 38 { 39 if(ans2 > a[treemin[cur]]) ans2 = a[treemin[cur]]; 40 return; 41 } 42 if(mid >= s) 43 querymin(ls, x, mid, s, t, ans2); 44 if(mid+1<= t) 45 querymin(rs, mid+1, y, s, t, ans2); 46 } 47 48 int solve(int x, int y) 49 { 50 int ans1 = -INF; 51 querymax(1,0,D-1,x,y,ans1); 52 int ans2 = INF; 53 querymin(1,0,D-1,x,y,ans2); 54 //printf("treemax[1]=%d\n",treemax[1]); 55 //printf("ans1 = %d ans2 = %d\n",ans1, ans2); 56 return ans1 - ans2; 57 } 58 void init() 59 { 60 while(~scanf("%d%d",&n,&m)) 61 { 62 for(int i = 1; i <= n; i ++) 63 scanf("%d",&a[i]); 64 for(D = 1; D < n + 2; D <<= 1); 65 for(int i = 0; i < D; i ++) 66 { 67 treemax[D+i] = i; 68 treemin[D+i] = i; 69 } 70 build(); 71 int A, B; 72 while(m --) 73 { 74 scanf("%d%d",&A,&B); 75 printf("%d\n",solve(A,B)); 76 } 77 } 78 } 79 int main() 80 { 81 init(); 82 return 0; 83 }