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 }