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 }

原文地址:https://www.cnblogs.com/shihuajie/p/2635785.html