poj 3468 A Simple Problem with Integers 线段树

  这道题属于线段树的区间修改

给出一个序列,对其进行Q次操作,

"C c" means adding c to each of AaAa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q b" means querying the sum of AaAa+1, ... , Ab.

注意,这道题我wa了4次,在那里查了3个小时,wa原因,一个应该是long long 型的被我写成了int  ,悲剧的开始。

    讲讲我对线段树区间修改的理解吧。

    需要有个操作,建树,更新,维护,查询。

  1.建树:首先就是把数据建起来嘛,是一个dfs的过程,对于一个节点,若该节点的区间只有一个,则为叶子节点,对该叶子进行赋值,否则建其左子树,和右子树,

然后在递归结束前进行维护,更新该节点本身的信息。

  2.更新:更新的时候不断递归,直到递归边界 (L<=l&&R>=r),对于每一个递归,在递归结束之前需要重新计算本节点的附加信息。

  3.维护:维护就是维护一个节点的信息,2中说要在递归 结束之前重新计算本节点的附加信息,怎么计算,就是用到维护这个操作了。

  4查询:查询的时候是不断递归,直到递归边界(L<=l&&R>=r) 时,用边界区间的附加信息更新答案。

  sum[i] : 维护 i 对应区间的数据的和。

     addv[i] : 表示 i 对应区间的每一个数据都需要加 addv[i] ,所以每一个边界区间的结果不能直接使用,还要考虑祖先节点对她的影响。

 

 1 #include<cstdio>

 2 #include<cstring>

 3 #define lson l,m,rt<<1

 4 #define rson m+1,r,rt<<1|1

 5 const int maxn=100000+10;

 6 long long  sum[maxn<<2];

 7 long long  addv[maxn<<2];

 8 void maintain(int l,int r,int rt)

 9 {

10     sum[rt]=0;

11     if(r>l)

12         sum[rt]=sum[rt<<1]+sum[rt<<1|1];

13     sum[rt]+=addv[rt]*(r-l+1);

14 }

15 void build(int l,int r,int rt)

16 {

17     if(l==r){

18         scanf("%I64d",&addv[rt]);

19     }

20     else{

21         int m=(l+r)>>1;

22         build(lson);

23         build(rson);

24     }

25     maintain(l,r,rt);

26 }

27 void update(int L,int R,int  w,int l,int r,int rt)

28 {

29     if(L<=l&&R>=r){

30         addv[rt]+=w;

31     }

32     else{

33         int m=(l+r)>>1;

34         if(L<=m)

35             update(L,R,w,lson);

36         if(R>m)

37             update(L,R,w,rson);

38     }

39     maintain(l,r,rt);

40 }

41 long long  _sum;

42 void query(int L,int R,int l,int r,int rt,long long  add)

43 {

44     if(L<=l&&R>=r)

45         _sum+=sum[rt]+add*(r-l+1);

46     else{

47         int m=(l+r)>>1;

48         if(L<=m)

49             query(L,R,lson,add+addv[rt]);

50         if(R>m)

51             query(L,R,rson,add+addv[rt]);

52     }

53 }

54 int main()

55 {

56     int n,q;

57     while(scanf("%d%d",&n,&q)!=EOF)

58     {

59         memset(addv,0,sizeof(addv));

60         build(1,n,1);

61         char s[3];

62         int u,v,w;

63         for(int i=1;i<=q;i++){

64             scanf("%s",&s);

65             if(s[0]=='C'){

66                 scanf("%d%d%d",&u,&v,&w);

67                 update(u,v,w,1,n,1);

68             }

69             else{

70                 scanf("%d%d",&u,&v);

71                 _sum=0;

72                 query(u,v,1,n,1,0);

73                 printf("%I64d\n",_sum);

74             }

75         }

76     }

77     return 0;

78 }
View Code

 

你可能感兴趣的:(Integer)