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 }

你可能感兴趣的:(树状数组)