HDU 1754 I Hate It(树状数组求区间最值)
看到HDU一个大牛写的一篇关于树状数组求区间最值的文章,根据文章做了这个题,研究一上午啊,那篇文章。。。
更假的是用GCC提交1000+,用C++交就500+。。。相同的代码,不同的编译器查这么多。。。
1 #include <stdio.h> 2 #include <string.h> 3 #define N 200001 4 int num[N],p[N]; 5 int n; 6 int lowbit(int t) 7 { 8 return t&(-t); 9 } 10 void change()//找最大值初始化 11 { 12 int i,j; 13 for(i = 1;i <= n;i ++) 14 { 15 p[i] = num[i]; 16 for(j = 1;j < lowbit(i);j <<= 1)//找比i小的数但又在lowbit(i)+1到i这个区间上的数更新p数组 17 { 18 if(p[i] < p[i-j])//j是以2倍的速度增长,这里不是很明白,可是这样写就是对的。。。 19 p[i] = p[i-j]; 20 } 21 } 22 } 23 void insert(int t,int sore) 24 { 25 num[t] = sore; 26 while(t <= n) 27 { 28 if(sore > p[t]) 29 p[t] = sore; 30 else 31 break; 32 t += lowbit(t); 33 } 34 } 35 int getmax(int l,int r)//找l到r之间的最大值 36 { 37 int ans = num[r]; 38 for(;;) 39 { 40 if(ans < num[r])//跟r位置上的数字比较 41 ans = num[r]; 42 if(l == r) break; 43 for(r = r-1;r-l >=lowbit(r);r -= lowbit(r)) 44 { 45 if(ans < p[r]) 46 ans = p[r]; 47 } 48 }//r自减1,判断r-lowbit(r)和l之间的关系如果l在区间内就不能减了而是继续循环 49 return ans;//如果l比r-lowbit(r)小的话,就可以之间判断ans和p[r]的最值了。 50 } 51 int main() 52 { 53 int m,i,id,sd,max; 54 char str; 55 while(scanf("%d%d",&n,&m)!=EOF) 56 { 57 memset(p,0,sizeof(p)); 58 for(i = 1;i <= n;i ++) 59 scanf("%d%*c",&num[i]); 60 change(); 61 for(i = 1;i <= m;i ++) 62 { 63 scanf("%c%d%d%*c",&str,&id,&sd); 64 if(str == 'Q') 65 { 66 max = getmax(id,sd); 67 printf("%d\n",max); 68 } 69 else if(str == 'U') 70 { 71 insert(id,sd); 72 } 73 } 74 } 75 return 0; 76 }