nyoj123 士兵杀敌(四)

 1 #include<stdio.h>

 2 #define N 1000010

 3 struct node{

 4     int l,r;

 5     int inc;

 6 }tree[3*N];

 7 inline void build(int l,int r,int i)

 8 {

 9     tree[i].l=l;

10     tree[i].r=r;

11     if(l<r){

12         int mid=(l+r)>>1;

13         build(l,mid,i<<1);

14         build(mid+1,r,(i<<1)+1);

15     }

16 }

17 inline void add(int l,int r,int inc,int i)

18 {

19     if(l==tree[i].l&&tree[i].r==r){//要是l为0的话就不能这样写了,否则RE,死循环 

20         tree[i].inc+=inc;//加的时候单单加到本段,不往下压 

21         return;

22     }

23     int mid=(tree[i].l+tree[i].r)>>1;

24     if(r<=mid) add(l,r,inc,i<<1);

25     else if(l>mid) add(l,r,inc,(i<<1)+1);

26     else{

27         add(l,mid,inc,i<<1);

28         add(mid+1,r,inc,(i<<1)+1);

29     }

30 }

31 inline int query(int k,int i)

32 {

33     if(tree[i].l<tree[i].r){//查询的时候父辈的inc值往下压,直到压到叶子节点为止 

34         if(tree[i].inc){

35             tree[i<<1].inc+=tree[i].inc;

36             tree[(i<<1)+1].inc+=tree[i].inc;

37             tree[i].inc=0;//记得清零 

38         }

39         int mid=(tree[i].l+tree[i].r)>>1;

40         if(k<=mid) return query(k,i<<1);

41         else return query(k,(i<<1)+1);

42     }

43     return tree[i].inc;//返回此叶子节点的值,也即是结果 

44 }

45 int main()

46 {

47     int a,b,inc,n,q;

48     char cmd[6];

49     scanf("%d%d",&q,&n);

50     build(1,n,1);

51     while(q--){

52         scanf("%s",cmd);

53         if(*cmd=='A'){

54             scanf("%d%d%d",&a,&b,&inc);

55             if(!a) a++;//真像讨论区有人说的那样本题测试数据有Bug,a可能为0,坑爹啊! 

56             add(a,b,inc,1);

57         }else{

58             scanf("%d",&a);

59             printf("%d\n",query(a,1));

60         }

61     }

62     return 0;

63 }

64 //本题貌似用树状数组做更加简洁,以后说吧!!先把线段树搞定!!


贴下最优代码:
 1 #include<cstdio>

 2 #include<cstring>

 3 const int M=1000010;

 4 int data[M];

 5 int Max;

 6 inline int LowBit(int n)

 7 {

 8     return n&(-n);

 9 }

10 void Plus(int n,int value) //前n项每项增加value

11 {

12     while(n>0)

13     {

14         data[n]+=value;

15         n-=LowBit(n);

16     }

17 }

18 int Get(int n) //获取每个位置的值

19 {

20     int sum=0;

21     while(n<=Max)

22     {

23         sum+=data[n];

24         n+=LowBit(n);

25     }

26     return sum;

27 }

28 char cmd[50];

29 int main()

30 {

31     int n,a,b,v;

32     scanf("%d%d",&n,&Max);

33     while(n--)

34     {

35         scanf("%s",cmd);

36         if(!strcmp(cmd,"ADD"))

37         {

38             scanf("%d%d%d",&a,&b,&v);

39             Plus(a-1,-v);

40             Plus(b,v);

41         }

42         else

43         {

44             scanf("%d",&a);

45             printf("%d\n",Get(a));

46         }

47     }

48     

49 

50 }
 
  

你可能感兴趣的:(OJ)